点击Tkinter子窗口图标后主窗口计时停止,如何解决?
解决方案
问题出在你用root.after()绑定计时回调,当子窗口获取焦点或被操作时,主窗口的事件循环会被暂时阻塞,导致计时停止。grab_set()会锁定所有交互到子窗口,显然不符合需求,你可以用以下两种方式解决:
方法一:使用全局Tkinter事件循环调度回调
把root.after(1000, nextTime)改成tk.after(1000, nextTime),这样回调绑定到整个Tkinter的事件循环而非主窗口,即使子窗口被操作,计时也会正常运行:
import tkinter as tk root = tk.Tk() label = tk.Label(root, text="timer = 0") label.pack() nowTime = 0 def nextTime(): global nowTime label.config(text=f"timer = {nowTime}") nowTime += 1 tk.after(1000, nextTime) # 使用全局的after方法 nextTime() # 子窗口 child = tk.Toplevel() tk.mainloop()
方法二:绑定子窗口焦点事件,重置计时回调
如果你需要保留窗口级别的after调用,可以监听子窗口的焦点事件,在子窗口获得焦点时重新调度计时回调:
import tkinter as tk root = tk.Tk() label = tk.Label(root, text="timer = 0") label.pack() nowTime = 0 after_id = None def nextTime(): global nowTime, after_id label.config(text=f"timer = {nowTime}") nowTime += 1 after_id = root.after(1000, nextTime) def on_child_focus(event): global after_id # 清除之前的回调并重新调度 if after_id: root.after_cancel(after_id) nextTime() nextTime() # 子窗口 child = tk.Toplevel() child.bind("<FocusIn>", on_child_focus) tk.mainloop()
推荐使用方法一,它更简洁且从根源上避免了窗口焦点影响计时的问题——全局after基于整个Tkinter事件循环,不受单个窗口状态干扰。
内容的提问来源于stack exchange,提问作者user14013165
相关产品推荐
相关产品推荐

