Tkinter实现的数字时钟运行10秒后停止、走时变慢原因咨询
问题原因
时钟启动10秒后停止更新、走时逐渐变慢的核心原因是定时任务被重复注册,数量呈指数级增长,最终阻塞了Tkinter的事件调度队列。
看你写的time()函数实现:
def time(): time_str = datetime.datetime.now().strftime("%H:%M:%S") date_str = datetime.datetime.now().strftime("%d.%m.%Y") time_label.config(text = time_str) time_label.after(1000, time) # 第一次注册定时任务 date_label.config(text = date_str) date_label.after(1000, time) # 第二次注册定时任务
你在单次函数执行里连续调用了两次after(1000, time),相当于每执行一次时间更新,就会新增2个1秒后再次执行time()的定时任务:
- 程序启动首次调用
time():注册2个待执行任务 - 1秒后2个任务同时触发,每个任务又各注册2个新任务,待执行任务总数变为4
- 再过1秒4个任务触发,待执行任务总数变为8
- 任务数按
2^n的规律指数增长:2→4→8→16→32→64→128→256→512→1024……
程序启动10秒左右待调度的任务数就会突破1000,Tkinter的单线程事件循环根本无法及时处理这么多任务,首先会出现调度延迟(表现为滴答间隔从预设的1秒变成2秒甚至更长),最终队列完全阻塞,时钟停止更新。
另外你的代码还有两个无关功能的小问题: - 导入了
strftime但全程没有使用,属于冗余导入 - 创建了多标签的Notebook组件,但所有时钟相关的标签都直接放在了根窗口,没有放到对应标签页内,创建的几个标签页都是空的
修复方案
只需要在time()函数里保留一个after定时注册即可,不需要给每个显示组件单独注册定时任务。修正后的完整代码如下:
from tkinter import * from tkinter import ttk import datetime root = Tk() root.title('Clock') tabs = ttk.Notebook(root) tabs.pack() clock_tab = ttk.Frame(tabs) timer_tab = ttk.Frame(tabs) stopwatch_tab = ttk.Frame(tabs) alarm_tab = ttk.Frame(tabs) international_time_tab = ttk.Frame(tabs) tabs.add(clock_tab, text='Clock') tabs.add(timer_tab, text='Timer') tabs.add(stopwatch_tab, text='Stopwatch') tabs.add(alarm_tab, text='Alarm') tabs.add(international_time_tab, text='International time') def time(): time_str = datetime.datetime.now().strftime("%H:%M:%S") date_str = datetime.datetime.now().strftime("%d.%m.%Y") time_label.config(text = time_str) date_label.config(text = date_str) # 仅注册一次定时循环即可 time_label.after(1000, time) # 时钟组件放入对应Clock标签页 time_label = Label(clock_tab,font = ('calibri', 20)) time_label.pack() date_label = Label(clock_tab,font = ('calibri', 15)) date_label.pack() exit_btn = ttk.Button( clock_tab, text = 'Exit', command = lambda: root.quit() ) exit_btn.pack(fill = 'x') def exit_func(event): root.quit() root.bind('<Return>', exit_func) time() mainloop()
内容的提问来源于stack exchange,提问作者Mark Pribylnov
相关产品推荐
相关产品推荐

