tkinter root.mainloop 与 While True 循环

2024-04-23

我正在使用 tkinter 根据我正在读取的电压显示一些标签。但是,它会在一次读取后停止执行。我发现这是由于 root.mainloop() 造成的。但我无法修复它。我已经包含了我的代码。 root.mainloop() 位于 while True 的末尾。

from Tkinter import *
import spidev
import time
import os
import RPi.GPIO as GPIO
import numpy

GPIO.cleanup()
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
adcvolt = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
batvolt = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

root = Tk() #Makes the window
w,h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0"%(w,h))

labelFont = ("times",15 ,"bold", "italic")
labelText1 = StringVar()
labelText2 = StringVar()
labelText3 = StringVar()
labelText4 = StringVar()
labelText5 = StringVar()
labelText6 = StringVar()

labelText1.set("Battery Management System")
label1 = Label(root, textvariable=labelText1, height=3, anchor="center")
label1.config(font=labelFont)
label1.pack()
labelText2.set("Wait")
label2 = Label(root, textvariable=labelText2, height=3, anchor="center")
label2.config(font=labelFont)
label2.pack()
labelText3.set("Wait")
label3 = Label(root, textvariable=labelText3, height=3, anchor="center")
label3.config(font=labelFont)
label3.pack()
labelText4.set("Wait")
label4 = Label(root, textvariable=labelText4, height=3, anchor="center")
label4.config(font=labelFont)
label4.pack()
labelText5.set("Wait")
label5 = Label(root, textvariable=labelText5, height=3, anchor="center")
label5.config(font=labelFont)
label5.pack()
labelText6.set("Wait")
label6 = Label(root, textvariable=labelText6, height=3, anchor="center")
label6.config(font=labelFont)
label6.pack()
#root.wm_title("Window Title") #Makes the title that will appear in the top left
#root.config(background = "#FFFFFF") #sets background color to white


# Open SPI bus
spi = spidev.SpiDev()
spi.open(0,0)

# Function to read SPI data from MCP3008 chip
# Channel must be an integer 0-7
def ReadChannel(channel):
  adc = spi.xfer2([1,(8+channel)<<4,0])
  data = ((adc[1]&3) << 8) + adc[2]
  return data

#Function to select multiplexer channel on 74HCT4067 chip
#Channel must be an integer 0-15
def MuxSelect(muxchannel):
    if muxchannel == 0:
        GPIO.output(7,0)
        GPIO.output(11,0)
        GPIO.output(13,0)
        GPIO.output(15,0)
    elif muxchannel == 1:
        GPIO.output(7,0)
        GPIO.output(11,0)
        GPIO.output(13,0)
        GPIO.output(15,1)
    elif muxchannel == 2:
        GPIO.output(7,0)
        GPIO.output(11,0)
        GPIO.output(13,1)
        GPIO.output(15,0)
    elif muxchannel == 3:
        GPIO.output(7,0)
        GPIO.output(11,0)
        GPIO.output(13,1)
        GPIO.output(15,1)
    elif muxchannel == 4:
        GPIO.output(7,0)
        GPIO.output(11,1)
        GPIO.output(13,0)
        GPIO.output(15,0)
    elif muxchannel == 5:
        GPIO.output(7,0)
        GPIO.output(11,1)
        GPIO.output(13,0)
        GPIO.output(15,1)
    elif muxchannel == 6:
        GPIO.output(7,0)
        GPIO.output(11,1)
        GPIO.output(13,1)
        GPIO.output(15,0)
    elif muxchannel == 7:
        GPIO.output(7,0)
        GPIO.output(11,1)
        GPIO.output(13,1)
        GPIO.output(15,1)
    elif muxchannel == 8:
        GPIO.output(7,1)
        GPIO.output(11,0)
        GPIO.output(13,0)
        GPIO.output(15,0)
    elif muxchannel == 9:
        GPIO.output(7,1)
        GPIO.output(11,0)
        GPIO.output(13,0)
        GPIO.output(15,1)
    elif muxchannel == 10:
        GPIO.output(7,1)
        GPIO.output(11,0)
        GPIO.output(13,1)
        GPIO.output(15,0)
    elif muxchannel == 11:
        GPIO.output(7,1)
        GPIO.output(11,0)
        GPIO.output(13,1)
        GPIO.output(15,1)
    elif muxchannel == 12:
        GPIO.output(7,1)
        GPIO.output(11,1)
        GPIO.output(13,0)
        GPIO.output(15,0)
    elif muxchannel == 13:
        GPIO.output(7,1)
        GPIO.output(11,1)
        GPIO.output(13,0)
        GPIO.output(15,1)
    elif muxchannel == 14:
        GPIO.output(7,1)
        GPIO.output(11,1)
        GPIO.output(13,1)
        GPIO.output(15,0)
    elif muxchannel == 15:
        GPIO.output(7,1)
        GPIO.output(11,1)
        GPIO.output(13,1)
        GPIO.output(15,1)



# Function to convert data to voltage level,
# rounded to specified number of decimal places. 
def ConvertVolts(data,places):
  volts = (data * 3.3) / 1023
  volts = round(volts,places)
  return volts

# Define sensor channels
voltage_channel = 0


# Define delay between readings
delay = 2




while True:
  count = 0

  while count<15:
    MuxSelect(count)

    # Read the voltage sensor data
    voltage_level = ReadChannel(voltage_channel)
    voltage_volts = ConvertVolts(voltage_level,2)
    adcvolt[count] = voltage_volts
    batvolt[count] = adcvolt[count] * 2.842

    #print adcvolt[count]
    #print batvolt[count]
    #print count
    count = count + 1
    #time.sleep(delay)
  labelText2.set('Cell1= '+str(batvolt[0])+'V  Cell2= ' +str(batvolt[1])+'V  Cell3= '+str(batvolt[2]))
  #root.update()
  labelText3.set('Cell4= '+str(batvolt[3])+'V  Cell5= ' +str(batvolt[4])+'V  Cell6= '+str(batvolt[5]))
 # root.update()
  labelText4.set('Cell7= '+str(batvolt[6])+'V  Cell8= ' +str(batvolt[7])+'V  Cell9= '+str(batvolt[8]))
#  root.update()
  labelText5.set('Cell10= '+str(batvolt[9])+'V  Cell11= ' +str(batvolt[10])+'V  Cell12= '+str(batvolt[11]))
#  root.update()
  labelText6.set('Cell13= '+str(batvolt[12])+'V  Cell14= ' +str(batvolt[13])+'V  Cell15= '+str(batvolt[14]))
  root.update()
  print "shit"  

  medianvolt = numpy.median(batvolt)
  maxvolt = max(batvolt)
  minvolt = min(batvolt)
  diff1 = maxvolt-medianvolt
  diff2 = medianvolt-minvolt

  if diff1>0.02 or diff2>0.02:
    GPIO.output (12,1)
    time.sleep(120)
    GPIO.output (12,0)


    # Wait before repeating loop
    time.sleep(delay)

  root.update()

  root.mainloop() #start monitoring and updating the GUI. Nothing below here runs.

tkinter needs mainloop()正确工作 - 它使用它一次又一次地调用所有需要的功能 - 即。从系统获取键/鼠标事件,将它们发送到小部件,更新值,并在窗口中(重新)绘制小部件。

In tkinter不要使用while True它会永远运行(或运行更长的时间),因为它会阻塞mainloop() in tkinter它无法更新窗口中的项目,而且看起来像是冻结了。

同样的问题使得sleep()- 它可以阻止mainloop() in tkinter.

您可以使用root.after(time_ms, function_name_without_brackets )(前mainloop())
延迟运行某些函数 - 所以它可以像这样使用sleep()。如果函数运行相同after(...)然后它会像循环一样工作。还有这样tkinter将有时间更新窗口中的小部件。


所以把你的所有代码while True(除了mainloop()) 在函数中并使用调用它after().
并使用第二个after()代替sleep().

import tkinter as tk

master = tk.Tk()

def my_mainloop():
    print "Hello World!"
    master.after(1000, my_mainloop)  # run again after 1000ms (1s)

master.after(1000, my_mainloop) # run first time after 1000ms (1s)

master.mainloop()

如果你无法转换while-循环并使用after()那么你可能必须在单独的线程中运行循环。但tkinter(像许多其他 GUI 一样)` 不喜欢在第二个线程中工作,并且 GUI 中的所有更改都必须在主线程中完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

tkinter root.mainloop 与 While True 循环 的相关文章

随机推荐

  • 使用 Spring beans 作为带有 @Cacheable 注释的键

    如何使以下工作发挥作用 一个 spring bean 该 bean 具有应使用 Cacheable 注释进行缓存的方法 另一个为缓存创建密钥的 spring bean KeyCreatorBean 所以代码看起来像这样 Inject pri
  • 在 Angular X 的子模块中使用 AppModule 中的组件(X 代表 2+)

    我创建了一个小组件 LoadingComponent 在我的应用程序的根目录中并在我的应用程序中 显然 声明了它AppModule 该组件在我的应用程序加载时使用 并且应该显示一些精美的加载动画 现在我想在保存某些内容时在子模块中使用它 但
  • 在 vm 脚本上下文中传递函数

    假设我有一个如下所示的库模块 module exports increment function count 我想在动态生成的脚本中使用它 如下所示 function lib increment 通过将其传递到沙箱中 var sandbox
  • 如何在 MKMapView 中保持图钉和地图在移动叠加层上方居中

    当我在地图上垂直移动 通过平移手势 另一个视图时 如何使图钉保持在地图的中心 以便图钉保持在覆盖层 而不是实际的 MapKit 覆盖层 上方 请参阅随附的第一个和最终状态的屏幕截图 当用户向上 向下平移时 我得到了覆盖层和屏幕顶部之间的空间
  • 如何将 WPF 复选框置于其可点击区域的中心?

    如果我在 WPF 中创建一个 CheckBox 控件 没有内容 我只需要选中 取消选中部分 它会放置 框 视觉对象 其中有或没有复选标记的 3D 矩形 位于控件的左上角 我可以将 盒子 视觉效果放在center而是使用 CheckBox 控
  • Emacs Windows 拼写检查 - aspell 或 hunspell

    我在Windows XP操作系统上使用emacs 23 1 50版本 我无法使用 emacs wiki 提供的示例将 hunspell 或 aspell 设置为 emacs 的一部分 任何人都有 Windows XP 的工作配置 请帮助我
  • 条件 DataGridView 格式设置

    我有一个 DataGridView 我将其 DataSource 属性设置为我自己的对象的 BindingList BindingList
  • 合并数据框,保留所有项目熊猫

    如何合并两个不同的数据帧 保留每个数据帧的所有行 同时填充空白 DF1 Name Addr Num Parent Parent Addr Matt 123H 8 James 543F Adam 213H 9 James 543F James
  • “Docker 子网”有什么用?

    docker desktop 中有一个选项允许更改 Docker 子网 我没有看到这个默认子网192 168 65 0 28被用在任何地方 我尝试过了docker network inspect在每个 Docker 内部网络上 检查了 do
  • Cordova config.xml 文件被重写

    我设置了一个基本的 Cordova 项目 每当我运行 cordova build 时 IOS 中的 config xml 文件都会被重写为默认值 并且我在项目文件夹的 config xml 中添加的任何首选项都会简单地附加到配置中 IOS平
  • SQL Server Management Studio 无法连接到 Sql Server

    我已经使用 MS Web Platform Installer 2 0 安装了 Visual Web Developer 2010 SQL Server 2008 R2 和 SQL Management Studio 2008 但每当我想登
  • Java 泛型(通配符)

    我有几个关于 Java 中通用通配符的问题 有什么区别List 基本上意味着
  • Symfony2:如何在FormType中调用实体的存储库

    我尝试调用我的实体的存储库Category以我的实体的类形 式BonCommande 但是出现了这个错误 注意 未定义的属性 C wamp www Symfony test src Application VehiculeBundle Fo
  • 如何在 Spring 加载应用程序上下文后立即执行作业?

    我想在加载 Spring 上下文后运行一些作业 但我不知道该怎么做 你知道该怎么做吗 另一种可能性是注册应用程序上下文事件的侦听器 基本上与skaffman的解决方案相同 只需实现 org springframework context A
  • 更改textNode值

    有什么方法可以更改 Web 浏览器中 DOM textNode 的值吗 我特别想看看能不能change现有节点 而不是creating一个新的 为了澄清这一点 我需要使用 Javascript 来完成此操作 浏览器中的所有文本都存储在 te
  • 旋转轴标签放置不正确(matplotlib)

    我想绘制带有旋转标签的相关矩阵 但是 标签放错了位置 如下所示 我试着看看Matplotlib Python 条形图 xtick 标签的位置彼此之间有不规则的空间 https stackoverflow com questions 2147
  • 如何阻止 LogCat 输出在 Eclipse 中自动滚动?

    UPDATE 事实证明 这是 SDK 工具 R14 中的一个错误 该问题已在 2013 年 10 月 27 日发布的 R15 中得到修复 更新到最新版本可以解决已接受答案中建议的问题 我使用 Eclipse 调试视图中的 LogCat 窗口
  • int 和 uint 使用的区别以及何时使用

    使用 int 和 uint 有什么区别 到目前为止我看到的所有示例都使用 int 表示整数 使用 uint 有什么好处吗 谢谢 uint means unsignedint 您可以将其用于 0 4G 范围其中正常 有符号 int的范围是 2
  • SignalR 不能与 .Net Core 一起使用

    我正在尝试安装SignalR在我的中使用 NuGet 包管理器C Asp Net 核心项目 但我收到此错误 称 SignalR 与 net core 不兼容 它真的还不支持吗 或者我可以做些什么来让它发挥作用吗 如果有必要提及的话 我正在使
  • tkinter root.mainloop 与 While True 循环

    我正在使用 tkinter 根据我正在读取的电压显示一些标签 但是 它会在一次读取后停止执行 我发现这是由于 root mainloop 造成的 但我无法修复它 我已经包含了我的代码 root mainloop 位于 while True