基于串行数据动态更新Tkinter窗口

use*_*445 5 python tkinter

我正在尝试编写一个从串行端口连接获取数据的程序,并根据该数据实时自动更新Tkinter窗口.

我试图为窗口创建一个单独的线程,定期从主线程获取当前数据并更新窗口,如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

运行它给了我这个错误:

异常螺纹加工-2:回溯(最近通话最后一个):文件"/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py",线路522,在__bootstrap_inner自我.运行()文件 "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)中)RuntimeError:主线程不在主循环中

当我谷歌这个错误时,我主要得到的帖子是人们试图从两个不同的线程与窗口交互,但我不认为我这样做.有任何想法吗?非常感谢!

Nic*_*ood 7

不要从线程运行TK gui - 从主进程运行它.我将你的例子捣碎成了证明这一原则的东西

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()
Run Code Online (Sandbox Code Playgroud)