0

I'm basically simulating acquiring data from the serial port and plotting it on a graph displayed in a GUI which is made using Tkinter. The incoming serial data is simulated by a simple while loop which calculates a sine function and adds the value to a queue which is size 100, the data generating part of the program is written under the class named 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

The other class generates the GUI , it creates an instance of the DataThread class and calling the function start_d should start the thread which generates the data. I would like to stop the thread by pressing the stop button but I'm not sure how to stop the thread.

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

And the last part which simply runs the GUI

if __name__ == "__main__":

    Application().run() 

I based my code of the following question: Dynamically updating Tkinter window based on serial data The difference being that both, the GUI thread and the data thread, are created simultaneously, but in my case it wouldn't work because I want to start the thread only when the start button is pressed.

Community
  • 1
  • 1
jquinno
  • 53
  • 1
  • 8

0 Answers0