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.