具有多线程Python的数据显示GUI

时间:2015-03-22 11:59:18

标签: python multithreading user-interface tkinter data-acquisition

我基本上模拟从串口获取数据并将其绘制在使用Tkinter制作的GUI中显示的图表上。传入的串行数据通过简单的while循环进行模拟,该循环计算正弦函数并将值添加到大小为100的队列中,程序的数据生成部分写在名为 DataThread <的类下/ p>

import Tkinter as tk
import numpy as np
import matplotlib as plt
from collections import deque
import threading 
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 
from time import sleep

class DataThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.ISCONNECTED = 1
        self.d = deque(maxlen=100)

    def run(self):
        t = 1        
        while True:
            wave = np.sin(2*np.pi*100*t*0.001)
            self.d.append(wave)
            print(wave)
            t = t+1
            sleep(1)
            if self.ISCONNECTED == 0:
                break

另一个类生成GUI,它创建 DataThread 类的实例,并且调用函数 start_d 应该启动生成数据的线程。我想通过按下停止按钮来停止线程,但我不确定如何停止线程。

class Application(tk.Frame): 
    def __init__(self, master=None):

        tk.Frame.__init__(self, master) 
        self.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W)) 


        self.fig = Figure()
        self.ax_1 = self.fig.add_subplot(111)

        self.createWidgets()
        self.a = DataThread()

    def createWidgets(self):        

        self.frame = tk.Frame(borderwidth=5, 
                          relief="sunken", width=300, height=20)
        self.frame.grid(column=0, row=0, columnspan=10, rowspan=4, 
                        sticky=(tk.N, tk.S, tk.E, tk.W))
        self.frame.rowconfigure(0, weight=1)
        self.frame.columnconfigure(0, weight=1)


        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)
        self.canvas.get_tk_widget().grid()

        self.canvas.show()


        self.namelbl = tk.Label(text="Start DAQ")
        self.namelbl.grid(column=10, row=0, columnspan=2,
                          sticky=(tk.S, tk.W), padx=5)

        self.start = tk.Button( text='Start',
                                command=self.quit)         

        self.start.grid(column=10, row=1,sticky=tk.N+tk.S+tk.E+tk.W)

        self.stop = tk.Button( text='Stop',
                                command=self.stop_serial)
        self.stop.grid(column=11, row=1,sticky=tk.N+tk.S+tk.E+tk.W)


    def start_d(self):
        self.a.ISCONNECTED=1
        self.a.start()

    def readSensor(self):
        data2plot = self.a.d
        self.ax_1.plot(range(data2plot),data2plot)
        self.root.update()
        self.root.after(527, self.readSensor)                

    def stop_serial(self):

        self.a.ISCONNECTED=0
    def run(self):
        self.mainloop()

最后一部分只是运行GUI

if __name__ == "__main__":

    Application().run() 

我的代码基于以下问题:Dynamically updating Tkinter window based on serial data 区别在于GUI线程和数据线程都是同时创建的,但在我的情况下它不会起作用,因为我只想在按下开始按钮时启动线程。

0 个答案:

没有答案