Tkinter Progressbar在print语句后启动,如何调整实现先启动进度条?
Tkinter Progressbar进度条延迟启动问题解决
问题原因
- Tkinter所有界面渲染、控件更新操作都依赖
root.mainloop()启动的事件循环处理,所有调用的控件方法(比如pb.start())只是把更新请求塞进事件队列,不会立刻触发界面刷新 - 你的代码在
pb.start()之后直接调用了阻塞主线程的time.sleep(5),这时候主线程被挂起,事件队列里的进度条启动、窗口初始化渲染请求全部无法被处理,直到sleep执行结束、进入root.mainloop()后才会批量处理之前积压的界面请求,所以会看到进度条在sleep结束后才启动。
修复方案
不要用time.sleep阻塞主线程,改用Tkinter自带的after()方法调度延时任务,保证事件循环能正常运行处理界面更新。修改后的代码如下:
from tkinter import Tk from tkinter.ttk import Progressbar import time # root window root = Tk() root.geometry('300x120') root.title('Progressbar Demo') root.grid() # progressbar pb = Progressbar( root, orient='horizontal', mode='indeterminate', length=280 ) # place the progressbar pb.grid(column=0, row=0, columnspan=2, padx=10, pady=20) pb.start() print("Before the sleep statement") # 定义延时执行的任务 def after_delay(): print("After the sleep statement") pb.stop() # 如需执行完任务关闭窗口可取消注释下一行 # root.destroy() # 调度5秒后执行任务,不会阻塞主线程 root.after(5000, after_delay) root.mainloop()
额外说明
如果你要执行的不是单纯的等待,而是实际的耗时业务逻辑,不要把耗时逻辑放在主线程执行,需要启动子线程运行耗时任务,任务结束后再通过root.after()调度主线程停止进度条,避免阻塞界面更新。
内容的提问来源于stack exchange,提问作者Adler Müller
相关产品推荐
相关产品推荐

