如何解决tkinter不确定进度条启动后无法正常运行5秒再停止的问题
问题根源
Tkinter是单线程事件驱动的UI框架,所有界面渲染、交互响应都靠主线程的事件循环调度。你在按钮回调里直接调用time.sleep(5)会完全阻塞主线程:
- 调用
start_p()后触发的进度条重绘任务会被压在事件队列里,根本没机会执行 - 阻塞的5秒内界面完全冻结,不会有任何更新
- 等5秒阻塞结束,代码立刻执行
stop_P(),进度条还没来得及渲染动画就被停止,就出现了你看到的异常现象。
修复方案
不要用time.sleep()做等待,改用Tkinter内置的after()方法实现定时任务:after()不会阻塞主线程事件循环,到达指定时长后会自动把要执行的任务加入事件队列调度。after()的时间单位是毫秒,等待5秒就传参5000,启动进度条后直接注册5秒后触发停止的任务即可。
修正后的完整代码:
from tkinter import * from tkinter import ttk def DOTEST_GUI(): GUI = Tk() w = 1920 h = 1080 ws = GUI.winfo_screenwidth() hs = GUI.winfo_screenheight() x = (ws/2) - (w/2) y = (hs/2) - (h/2) GUI.geometry(f'{w}x{h}+{x:.0f}+{y:.0f}') def start_p(): progress.start(5) def stop_P(): progress.stop() def print_cf(event = None): print('s') start_p() # 移除time.sleep阻塞,用after注册5秒后执行的停止任务 GUI.after(5000, stop_P) B_TEST = ttk.Button(GUI, text = "test", width = 15, command = print_cf) B_TEST.pack() progress = ttk.Progressbar(GUI, orient = HORIZONTAL, length = 100, mode = 'indeterminate') progress.pack(pady = 10) GUI.bind("<Return>", print_cf) GUI.focus() GUI.mainloop() DOTEST_GUI()
补充说明:如果你的
time.sleep原本是用来等待其他耗时任务执行,不要把耗时任务直接放在主线程跑,要放到子线程里执行,执行完再通过after()回调回到主线程更新UI,否则还是会出现界面冻结的问题。
内容的提问来源于stack exchange,提问作者Vittawat Laorungroj
相关产品推荐
相关产品推荐

