Kontinuierlicher Zugriff auf Threads in der tkinter-Schleife
Ich versuche, eine GUI zu erstellen, die kontinuierlich ein von einem Mikroprozessor empfangenes Signal zeichnet. Ich habe versucht, dies nur mithilfe von Klassen zu erreichen, aber das schlug fehl, da nur die GUI-Klasse geöffnet war. Jetzt habe ich Threading implementiert (oder glaube ich zumindest !?), aber jeder Thread wird nur einmal ausgeführt. was mich glauben lässt, dass ich nicht verstehe, wie die Hauptschleife in tkinter funktioniert, kann ich meinen Code also neu erstellen, damit die Threads aktiv werden?
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()
Ich hoffe, einige von Ihnen können mir helfen, diesen Code zu einem Programm zu machen, das einen Plot in Echtzeit aktualisiert.
Super ich habe folgendes im Programm geändert,
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()
Aber die geplotteten Zahlen werden immer noch nicht aktualisiert. Sollte dies nicht in der Foo-Klasse der Fall sein? Auch jetzt, wenn ich oder ziemlich das Python-Skript beende, verbraucht es immer noch 50% der CPU-Leistung, wahrscheinlich, weil der Sensor-Thread jetzt für immer läuft !?