python+Tkinter+多線程的實例
python+Tkinter+多線程
界面和多線程一向是編程里比較難的地方,常見的做法一般是界面一個線程,后臺新開一個工作線程,這兩個線程進行通信,這樣可以讓界面不至于為響應(yīng)。
在python中可以利用隊列完成整體的架構(gòu)設(shè)計。
直接給大家看代碼吧,一個簡單實例,非常好的例子。
import Tkinter,time,threading,random,Queue class GuiPart(): def __init__(self,master,queue,endCommand): self.queue=queue Tkinter.Button(master,text='Done',command=endCommand).pack() def processIncoming(self): while self.queue.qsize(): try: msg=self.queue.get(0) print msg except Queue.Empty: pass class ThreadedClient(): def __init__(self,master): self.master=master self.queue=Queue.Queue() self.gui=GuiPart(master,self.queue,self.endApplication) self.running=True self.thread1=threading.Thread(target=self.workerThread1) self.thread1.start() self.periodicCall() def periodicCall(self): self.master.after(200,self.periodicCall) self.gui.processIncoming() if not self.running: self.master.destroy() def workerThread1(self): #self.ott=Tkinter.Tk() #self.ott.mainloop() while self.running: time.sleep(rand.random()*1.5) msg=rand.random() self.queue.put(msg) def endApplication(self): self.running=False rand=random.Random() root=Tkinter.Tk() client=ThreadedClient(root) root.mainloop()
tkinter與多線程問題
長時間執(zhí)行后臺任務(wù),UI會處于無響應(yīng)狀態(tài)。在子線程里更新UI狀態(tài),聽說是不允許的。在哪個線程里調(diào)用了tk.mainloop(),就只能在哪個線程里更新UI。
下例演示了如何更新。
import Tkinter as tk from ttk import * import time import Queue, threading class MainWindow: def __init__(self): self.root = tk.Tk() self.root.title('Demo') def show(self): self.progress = tk.IntVar() self.progress_max = 100 self.progressbar = Progressbar(self.root, mode='determinate', orient=tk.HORIZONTAL, variable=self.progress, maximum=self.progress_max) self.progressbar.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.progress.set(0) btn = tk.Button(self.root, text='start', command=self.start) btn.pack(fill=tk.BOTH, expand=True, padx=15, pady=5) self.btn = btn self.root.mainloop() def start(self): self.progress.set(0) self.btn.config(state=tk.DISABLED) self.thread_queue = Queue.Queue() # used to communicate between main thread (UI) and worker thread new_thread = threading.Thread(target=self.run_loop, kwargs={'param1':100, 'param2':20}) new_thread.start() # schedule a time-task to check UI # it's in main thread, because it's called by self.root self.root.after(100, self.listen_for_result) def run_loop(self, param1, param2): progress = 0 for entry in range(self.progress_max): time.sleep(0.1) progress = progress + 1 self.thread_queue.put(progress) def listen_for_result(self): ''' Check if there is something in the queue. Must be invoked by self.root to be sure it's running in main thread ''' try: progress = self.thread_queue.get(False) self.progress.set(progress) except Queue.Empty: # must exist to avoid trace-back pass finally: if self.progress.get() < self.progressbar['maximum']: self.root.after(100, self.listen_for_result) else: self.btn.config(state=tk.NORMAL) if __name__ == '__main__': win = MainWindow() win.show()
一個進度條。設(shè)定最大進度為100。在子線程里每隔0.1秒更新一格。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 與GO中操作slice,list的方式實例代碼
這篇文章主要介紹了python 與GO中操作slice,list的方式實例代碼的相關(guān)資料,需要的朋友可以參考下2017-03-03Python數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)代碼示例
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)代碼示例,簡單介紹了順序表的相關(guān)內(nèi)容,然后分享了其代碼示例,具有一定參考價值,需要的朋友可以了解下。2017-11-11利用Python實現(xiàn)文件讀取與輸入以及數(shù)據(jù)存儲與讀取的常用命令
這篇文章主要給大家介紹了關(guān)于利用Python實現(xiàn)文件讀取與輸入以及數(shù)據(jù)存儲與讀取的常用命令,文中還介紹了用python循環(huán)保存文件并循環(huán)讀取文件的方法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11Tensorflow tf.nn.depthwise_conv2d如何實現(xiàn)深度卷積的
這篇文章主要介紹了Tensorflow tf.nn.depthwise_conv2d如何實現(xiàn)深度卷積的,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Python實現(xiàn)嵌套列表的7中方法總結(jié)
這篇文章主要來給大家講解一個Python的進階知識點:如何將一個嵌套的大列表展開形成一個列表。小編提供了7種方法供大家學(xué)習(xí)參考,希望大家能喜歡2023-03-03