我有一个python模块“命令行阅读器”,通过RFID与一个小型电子单元进行通信。我想创建一个使用该程序的GUI,并进一步处理数据。
我的问题是GUI标签没有更新。我尝试使用论坛中提出的线程和队列,但标签在代码完成之前仍然没有。 以下是我从此示例改编的简化代码:http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/
谁能告诉我我做错了什么?
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()
答案 0 :(得分:0)
您的问题可能是这两个循环,但可能还有其他问题:
while self.out_queue.empty():
time.sleep(1)
print 'wait...'
...
while output[-1] != 'done':
time.sleep(2)
print 'wait...'
你永远不应该在GUI线程中调用sleep
,因为它会阻止GUI响应事件。