在 tkinter 循环中不断访问线程 [英] accessing threads continually in tkinter loop

查看:65
本文介绍了在 tkinter 循环中不断访问线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个连续绘制从微处理器接收到的信号的 GUI.我试图仅通过使用类来实现这一点,但由于只有 GUI 类是开放的,所以失败了.现在我已经实现了线程(或者至少我认为我有!?)但是每个线程只运行一次.这让我相信我不明白 tkinter 中的主循环是如何工作的,所以我可以重新编写我的代码以使线程变为活动状态吗?

I am trying to make a GUI that continually plot a signal received from a micro processor. I have tried to make this happen by use of classes only, but that failed since only the GUI class was oppend. Now i have implemented threading (or at least I think I have!?) but each thread is only run once. which make me believe that I don't understand how the mainloop in tkinter works, so can I remake my code in away that the threads become active?

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() 

我希望你们中的一些人可以帮助我把这段代码变成一个实时更新情节的程序.

I hope some of you can help my make this code become a program that realtime updates a plot.

超级我在程序中更改了以下内容,

Super I have changed the following in the program,

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() 

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

but it still doesn't update the figure that are plottet, shouldn't it do this in the Foo class? Also now when I exit or quite the python script it still uses 50% of CPU power probably because the Sensor thread now runs for ever!?

推荐答案

看看这个配方,它展示了如何去做:

Check out this recipe, it shows how to do it:

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

这篇关于在 tkinter 循环中不断访问线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆