当前位置: 首页 > 知识库问答 >
问题:

在tkinter循环中连续访问线程

岳志义
2023-03-14

我试图制作一个图形用户界面,不断绘制从微处理器接收的信号。我试图通过只使用类来实现这一点,但是失败了,因为只有GUI类是oppend。现在我已经实现了线程(或者至少我认为我有!?)但是每个线程只运行一次。这让我相信我不明白tkinter中的主循环是如何工作的,所以我可以重新编写我的代码,让线程变得活跃吗?

import Tkinter
import tkMessageBox as messagebox
from serial import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
import time
import threading

go=0

x=[0.0001,0.0002,0.0003]
y=[3600,1000,2000]
stid=time.time()

root = Tkinter.Tk()
root.title("Serial gui")

class SensorThread(threading.Thread):
    def run(self):
        global run
        global x
        global y
        global stid
        print "run er ok"
        if go==1:
            print "go er ok"
            ser = Serial(5, 9600, timeout=1)
            f=ser.read(4)
            ser.close()
            x.append(time.time()-stid)
            y.append(f)


class Foo:
    def __init__(self, master):
        print "foo ok"

        frame = Tkinter.Frame(root)

        self.button_left = Tkinter.Button(frame,text="Start",
                                command=self.start)
        self.button_left.pack(side="left")

        self.button_right = Tkinter.Button(frame,text="Stop",
                                command=self.stop)
        self.button_right.pack(side="right")

        self.button_midt = Tkinter.Button(frame, text='Quit', command=self.terminate)
        self.button_midt.pack(side="bottom")

        fig = Figure()
        ax = fig.add_subplot(111, axisbg='black')

        canvas = FigureCanvasTkAgg(fig,master=master)
        canvas.show()
        canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
        frame.pack()

        line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma
        line1.set_ydata(y)
        fig.canvas.draw()


    def start(self):
        global go
        go=1
        print go

    def stop(self):
        global go
        go=0
        print go

    def terminate(self):
        root.quit()     # stops mainloop
        root.destroy()  # this is necessary on Windows to prevent
                        # Fatal Python Error: PyEval_RestoreThread: NULL tstate

if __name__ == "__main__":
    SensorThread().run()
    Foo(root)
    root.mainloop() 

我希望你们中的一些人能帮助我把这段代码变成一个实时更新绘图的程序。

class SensorThread(threading.Thread):
def run(self):
    global run
    global x
    global y
    global stid
    #print "run er ok"
    if go==1:
        print "go er ok"
        ser = Serial(17, 9600, timeout=1)
        f=ser.read(4)
        ser.close()
        x.append(time.time()-stid)
        y.append(f)
        SensorThread().start()
    else:
        SensorThread().start()

class Foo:
....

if __name__ == "__main__":
SensorThread().start()
Foo(root)
root.mainloop() 

但是它仍然没有更新plottet的图形,它不应该在Foo类中这样做吗?现在,当我退出python脚本或完全退出python脚本时,它仍然使用50%的CPU功率,可能是因为传感器线程现在永远运行!?

共有1个答案

楚天宇
2023-03-14

看看这个食谱,它展示了如何做:

http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/

 类似资料:
  • 我正在为我的公司开发一个“多层”GUI来监控温度和状态。因为我是python编程新手,所以我的代码需要一些帮助。 代码由类构成。“Main”初始化主窗口(tkinter)并创建其他要显示的帧(如果需要)。除“canvas”外,其他每个类都是一个框架,它将显示不同的内容。 每个画布都包含一个图像和一些文本/可变文本。线程用于从数据库获取数据并更改画布中的文本。 每次线程访问画布并尝试更改文本或创建新

  • 我有一个tar.gz文件,里面有大量的小xml文件(略少于1.5m)(没有子目录)。现在我想遍历这些文件,我正在尝试使用apache公共压缩来实现这一点。我不想像在类似主题中经常看到的那样输出或写入任何东西到新文件中。我只想逐步读取信息(完美的是能够在某个点停止并继续运行另一个程序,但那是次要的)。 因此,对于初学者,我认为我应该从这样的事情开始(计数器只是为了测试目的而存在以减少时间): 但是e

  • 问题内容: 如何从单独的对象调用tkinter ? 我在寻找类似wxWidgets的东西。例如,如果我创建一个对象,并将其根实例传递给它,然后尝试从我的对象中调用该根窗口的方法,则我的应用程序将锁定。 我能想到的最好的方法是使用该方法并从单独的对象检查状态,但这似乎很浪费。 问题答案: 要回答“如何从单独的对象调用TkInter事件”这一特定问题,请使用命令。它允许您将事件注入到根窗口的事件队列中

  • 问题内容: 我有这个脚本: 但被警告两次,而不是那么。 有没有一种方法可以传递而不将函数编写为字符串? 问题答案: 您必须为每个超时功能安排一个单独的“ i”副本。 如果您不做这样的事情(同一想法还有其他变体),那么每个计时器处理程序函数将 共享 相同的变量“ i”。循环结束后,“ i”的值是多少?3!通过使用中间函数,将 复制 变量的值。由于超时处理程序是在该副本的上下文中创建的,因此它具有自己

  • 问题内容: 谁能为我指出正确的方向,为什么该代码将无法连续播放此音频剪辑?它播放一次然后停止。 问题答案: 如果您运行的是更大的应用程序,则此答案可能不适用。但是对于仅使用那段代码的简单测试,这 可能会 有所帮助: Clip.loop()启动它自己的线程,但是该线程不会使JVM保持活动状态。因此,要使其工作,请确保夹子不是唯一的螺纹。 如果我从此代码段中删除Thread.sleep(..),则会遇

  • 所以我必须在eclipse中为我的类创建一个java项目。分配是创建一个程序,允许用户在程序中输入整数,直到输入某个整数(42)。输入整数(42)后,程序将为1。平均输入的所有数字。2、显示输入的最小值和最大值。3、输入的数字总数。这些必须在不计算(42)的情况下进行计算。这就是我目前所拥有的。我可以从用户那里获得输入,一旦他们输入42,程序就会停止并显示总数,但包括42。我不知道如何为输入添加一