您当前的位置:首页 > IT编程 > python
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 |

自学教程:python+Tkinter+多线程的实例

51自学网 2023-06-16 18:56:03
  python
这篇教程python+Tkinter+多线程的实例写得很实用,希望能帮到您。

python+Tkinter+多线程

界面和多线程一向是编程里比较难的地方,常见的做法一般是界面一个线程,后台新开一个工作线程,这两个线程进行通信,这样可以让界面不至于为响应。

在python中可以利用队列完成整体的架构设计。

直接给大家看代码吧,一个简单实例,非常好的例子。

import Tkinter,time,threading,random,Queueclass 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:                passclass 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=Falserand=random.Random()root=Tkinter.Tk()client=ThreadedClient(root)root.mainloop()

tkinter与多线程问题

长时间执行后台任务,UI会处于无响应状态。在子线程里更新UI状态,听说是不允许的。在哪个线程里调用了tk.mainloop(),就只能在哪个线程里更新UI。

下例演示了如何更新。

import Tkinter as tkfrom ttk import *import timeimport Queue, threadingclass 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()

一个进度条。设定最大进度为100。在子线程里每隔0.1秒更新一格。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持wanshiok.com。


Python技巧之四种多线程应用分享
基于tkinter中ttk控件的width-height设置方式
51自学网自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1