accediendo a hilos continuamente en tkinter loop
Estoy tratando de hacer una GUI que traza continuamente una señal recibida de un microprocesador. He intentado hacer que esto suceda mediante el uso de clases solamente, pero eso falló porque solo la clase GUI estaba habilitada. Ahora he implementado subprocesos (¡o al menos creo que sí !?) pero cada subproceso solo se ejecuta una vez. lo que me hace creer que no entiendo cómo funciona mainloop en tkinter, así que ¿puedo rehacer mi código de manera que los hilos se activen?
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()
Espero que algunos de ustedes puedan ayudarme a hacer que este código se convierta en un programa que actualice en tiempo real una trama.
Super, he cambiado lo siguiente en el programa,
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()
pero aún no actualiza la figura que es plottet, ¿no debería hacer esto en la clase Foo? También ahora, cuando salgo o la secuencia de comandos de python sigue usando el 50% de la potencia de la CPU, probablemente, ¡porque el hilo del sensor ahora se ejecuta para siempre.