0

私は基本的に、シリアルポートからデータを取得し、Tkinter を使用して作成された GUI に表示されるグラフにプロットすることをシミュレートしています。入力シリアル データは、正弦関数を計算し、サイズ 100 のキューに値を追加する単純な while ループによってシミュレートされます。プログラムのデータ生成部分は、DataThreadという名前のクラスの下に記述されます。

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

次の質問のコードに基づいています:シリアル データに基づいて Tkinter ウィンドウを動的に更新する 違いは、GUI スレッドとデータ スレッドの両方が同時に作成されることですが、私の場合は、スタートボタンを押したときだけ糸を通す。

4

0 に答える 0