ciągły dostęp do wątków w pętli tkinter
Próbuję stworzyć GUI, który nieustannie wykreśla sygnał otrzymany z mikroprocesora. Próbowałem to zrobić tylko za pomocą klas, ale to się nie powiodło, ponieważ przeciwna była tylko klasa GUI. Teraz zaimplementowałem wątkowanie (a przynajmniej myślę, że mam !?), ale każdy wątek jest uruchamiany tylko raz. co sprawia, że wierzę, że nie rozumiem, jak działa mainloop w tkinter, więc czy mogę przerobić mój kod, aby wątki stały się aktywne?
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()
Mam nadzieję, że niektórzy z was pomogą mojemu kodowi stać się programem, który w czasie rzeczywistym aktualizuje fabułę.
Super Zmieniłem poniższy 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()
ale nadal nie aktualizuje postaci, która jest plottet, czy nie powinno to zrobić w klasie Foo? Również teraz, gdy wychodzę ze skryptu Pythona lub całkiem go nie używam, nadal zużywa on 50% mocy procesora, prawdopodobnie dlatego, że wątek Sensor działa teraz na zawsze !?