2014-01-24 50 views
0

我有一個python模塊「命令行閱讀器」,通過RFID與小型電子單元進行通信。我想創建一個使用此程序的GUI並進一步處理數據。Python: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

你的問題很可能是這兩個環,雖然可能有其他的問題:

while self.out_queue.empty(): 
    time.sleep(1) 
    print 'wait...' 
... 
while output[-1] != 'done': 
    time.sleep(2) 
    print 'wait...' 

'

你應該永遠不會調用sleep在GUI線程,因爲它可以防止GUI響應事件。

+0

所以我重寫了沒有使用睡眠功能的循環,但沒有改變...任何其他建議? – user3197620

+0

找到解決方案:GUI被阻止,直到def(go)完成。因此,只需在def(go)中啓動線程並使用單獨的方法處理out_queue即可完成這項工作...... – user3197620

相關問題