I have a python module "commandline reader" that communicates via RFID with a small electronic unit. I want to create a GUI that uses this program and further processes the data.
My problem was that the GUI labels didn't update. I tried to use threading and queues as proposed in the forum, but the labels still don't before the code is finished. Here's my simplified code adapted from this example: http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/
Can anyone tell me what I'm doing wrong?
from GUI_reader import Commandline_Reader
from Tkinter import *
import Tkinter as ttk
import ttk
import time
import threading
import Queue
class GuiPart:
def __init__(self, master, queue, out_queue, check_queue):
self.queue = queue
self.out_queue = out_queue
self.check_queue = check_queue
self.master = master
self.master.title("AO Fracture Monitor")
self.patid = StringVar()
self.text = StringVar()
self.startvar = BooleanVar()
# Patient ID
idf = ttk.Labelframe(master, text='Patient ID')
idf.grid(column=0, row=0, sticky=(N,E,W,S))
self.idl = ttk.Label(idf, text='none')
self.idl.grid(padx=5, pady=(5,10))
# Info text
self.infotext = Label(master, height=6, text='first', justify='left', anchor=N)
self.infotext.grid(row=1, column=0, padx=5, pady=5, sticky=(N,E,S,W))
#Start button
button = ttk.Checkbutton(master, text='Start', variable=self.startvar, style='TButton', command=self.go)
button.grid(column=0, row=2, sticky=(E,S,W))
def go(self):
ThreadedClient(root).go()
def processIncoming(self):
while self.check_queue.qsize():
try:
text = self.check_queue.get(0)
# text = ['text', 'searching for logger'],['ID', '266525']
if text[0] == 'ID':
print text
self.idl.configure(text=text[1])
self.infotext.configure(text='Process executed')
elif text[0] == 'text':
print text
self.infotext.configure(text=text[1])
except self.check_queue.empty():
pass
class ThreadedClient:
def __init__(self, master):
self.master = master
self.queue = Queue.Queue()
self.out_queue = Queue.Queue()
self.check_queue = Queue.Queue()
self.gui = GuiPart(master, self.queue, self.out_queue, self.check_queue)
self.running = True
def go(self):
self.queue.put('-s --get_serial_number')
self.thread = threading.Thread(target = self.workerThread1)
self.thread.start()
self.periodicCall()
self.check_queue.put(['text','searching for logger'])
while self.out_queue.empty():
time.sleep(1)
print 'wait...'
output = self.out_queue.get()
# output = ['COM3' , ... , 'done']
while output[-1] != 'done':
time.sleep(2)
print 'wait...'
for i, s in enumerate(output):
if 'serial_number' in s:
ID = output[i]
# ID = 'serial_number=266525'
self.check_queue.put(['ID',ID[14:]])
def periodicCall(self):
self.gui.processIncoming()
if not self.running:
return
self.master.after(100, self.periodicCall)
def workerThread1(self):
self.argString = self.queue.get()
reader = Commandline_Reader(self.argString)
if reader.connect():
self.out_queue.put(reader.run())
if reader.output[-1] == 'done':
self.queue.task_done()
self.running = False
if __name__ == "__main__":
root = Tk()
client = ThreadedClient(root)
root.mainloop()
Your problem is likely these two loops, though there may be other problems:
while self.out_queue.empty():
time.sleep(1)
print 'wait...'
...
while output[-1] != 'done':
time.sleep(2)
print 'wait...'
'
You should never, ever call sleep
in the GUI thread, because it prevents the GUI from responding to events.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.