Guizero/TKinter计时器GUI冻结崩溃问题技术求助
嘿,这个问题我太熟了——你踩了GUI编程里最常见的坑之一:阻塞事件循环!
问题根源
当你点击Start按钮后,test_loopt里的while timeLoop循环加上time.sleep(1)会把GUI的主线程死死占住。GUI程序的核心是事件循环,它要处理按钮点击、界面更新这些事儿,结果你让它一直跑循环睡大觉,自然没法响应Stop按钮,系统一看GUI僵住了,就直接给你强制关闭了。
修复方案
我们需要用guizero内置的repeat方法来实现非阻塞的计时,这样GUI主线程能同时处理用户交互和计时任务。下面是修改后的完整代码:
修复后的代码
###import libraries ### from guizero import * import time ###Variables### timeLoop = False Sec = 0 Min = 0 Hour = 0 test_repeat_id = None # 保存定时任务ID,用于停止计时 ###Define Functions### def verlaat_settings(): window2.hide() window3.hide() window4.hide() window.show(wait=True) def stop_test(): global timeLoop, test_repeat_id if test_repeat_id is not None: app.cancel(test_repeat_id) # 取消定时任务 test_repeat_id = None info("test_result", f"Test stopped at {Hour} Hour {Min} Mins {Sec} Sec ") text_test.value = "Test Stopped..." timeLoop = False def update_timer(): global Sec, Min, Hour Sec += 1 print(f"{Min} Mins {Sec} Sec ") # 实时更新GUI上的计时器显示 timer_test.value = f"{Hour:02d}:{Min:02d}:{Sec:02d}" if Sec == 60: Sec = 0 Min += 1 if Min == 60: Min = 0 Hour += 1 def test_loopt(): global timeLoop, test_repeat_id if not timeLoop: text_test.value = "Test is running....." timeLoop = True # 每隔1000毫秒(1秒)触发一次计时更新 test_repeat_id = app.repeat(1000, update_timer) app= App(title="Profiberry", layout="", width=480, height=272) window3 = Window(app, title="Profiberry-Tester", layout="grid", width=480, height=272) window3.show() # 补全括号,否则窗口不会显示 ###Window3### welkom_tester= Text(window3, text="Profibus Tester", grid=[2,0,1,1]) Plaatje_profi= Picture(window3, image="logoprofi.gif", grid=[2,1,1,1]) lege_ruimte1 = Text(window3, text="", grid=[2,2,1,1]) text_test= Text(window3, text=" Waiting for input..... ", grid=[2,3,1,1]) timer_test= Text(window3, text='', grid=[2,4,1,1] ) lege_ruimte2 = Text(window3, text="", grid=[2,5,1,1]) lege_ruimte2 = Text(window3, text="", grid=[1,6]) Start_knop= PushButton(window3, text="Start", command=test_loopt, padx=50, pady=10, grid=[1,6] ) Start_knop.tk.config(foreground="white", background="green") Stop_knop= PushButton(window3, text="Stop", command=stop_test, padx=50, pady=10, grid=[3,6]) Stop_knop.tk.config(foreground="white", background="red") Exit_setting = PushButton(window3, command=verlaat_settings, text="Exit to Main Menu(F2)", padx=30, pady=10, grid=[2,6]) app.display()
关键改动说明
- 移除阻塞循环:删掉了
test_loopt里的while和time.sleep,改用app.repeat()定时触发计时更新,不会抢占GUI主线程。 - 定时任务管理:新增
test_repeat_id变量保存定时任务的ID,点击Stop时可以用app.cancel()终止计时。 - 修复语法错误:把
stop_test里的timeLoop: False改成正确的全局变量声明+赋值。 - 界面实时更新:在
update_timer里同步更新GUI上的timer_test文本,让用户能直观看到计时进度。 - 补全方法调用:修复了
window3.show漏写括号的问题,确保窗口正常显示。
这样修改后,点击Start按钮计时开始,GUI不会冻结,Stop按钮能正常响应,程序也不会被系统强制关闭了。
内容的提问来源于stack exchange,提问作者Robin46
相关产品推荐
相关产品推荐

