问题描述
我正在尝试编写一个程序,该程序从串行端口连接获取数据并根据该数据实时自动更新 Tkinter 窗口.
I'm trying to write a program that gets data from a serial port connection and automatically updates the Tkinter window in real time based on that data.
我尝试为窗口创建一个单独的线程,该线程定期从主线程获取当前数据并更新窗口,如下所示:
I tried to create a separate thread for the window that periodically gets the current data from the main thread and updates the window, like this:
serialdata = []
data = True
class SensorThread(threading.Thread):
def run(self):
serial = serial.Serial('dev/tty.usbmodem1d11', 9600)
try:
while True:
serialdata.append(serial.readline())
except KeyboardInterrupt:
serial.close()
exit()
class GuiThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.root = Tk()
self.lbl = Label(self.root, text="")
def run(self):
self.lbl(pack)
self.lbl.after(1000, self.updateGUI)
self.root.mainloop()
def updateGUI(self):
msg = "Data is True" if data else "Data is False"
self.lbl["text"] = msg
self.root.update()
self.lbl.after(1000, self.updateGUI)
if __name == "__main__":
SensorThread().start()
GuiThread().start()
try:
while True:
# A bunch of analysis that sets either data = True or data = False based on serialdata
except KeyboardInterrupt:
exit()
运行它给我这个错误:
线程 Thread-2 中的异常:回溯(最近一次调用最后一次):文件/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py",第 522 行,在 __bootstrap_innerself.run()运行中的文件analysis.py",第 52 行self.lbl1.pack()文件/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py",第 1764 行,在 pack_configure 中+ self._options(cnf, kw))运行时错误:主线程不在主循环中
当我用谷歌搜索这个错误时,我经常收到人们试图从两个不同的线程与窗口交互的帖子,但我认为我没有这样做.有任何想法吗?非常感谢!
When I google this error, I mostly get posts where people are trying to interact with the window from two different threads, but I don't think I'm doing that. Any ideas? Thanks so much!
推荐答案
不要从线程运行 TK gui - 从主进程运行它.我把你的例子捣碎成说明原理的东西
Don't run the TK gui from a thread - run it from the main process. I mashed your example into something that demonstrates the principle
from time import sleep
import threading
from Tkinter import *
serialdata = []
data = True
class SensorThread(threading.Thread):
def run(self):
try:
i = 0
while True:
serialdata.append("Hello %d" % i)
i += 1
sleep(1)
except KeyboardInterrupt:
exit()
class Gui(object):
def __init__(self):
self.root = Tk()
self.lbl = Label(self.root, text="")
self.updateGUI()
self.readSensor()
def run(self):
self.lbl.pack()
self.lbl.after(1000, self.updateGUI)
self.root.mainloop()
def updateGUI(self):
msg = "Data is True" if data else "Data is False"
self.lbl["text"] = msg
self.root.update()
self.lbl.after(1000, self.updateGUI)
def readSensor(self):
self.lbl["text"] = serialdata[-1]
self.root.update()
self.root.after(527, self.readSensor)
if __name__ == "__main__":
SensorThread().start()
Gui().run()
这篇关于基于串口数据动态更新Tkinter窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!