python - 为什么 tkinter 中的 after 函数的延迟比实际秒数多
问题描述
我正在制作一个使用计时器的 gui 程序,所以我使用 after 函数一次又一次地循环该函数,但延迟为 1 毫秒。但我将它与谷歌中的一个实际计时器进行了比较,它略微偏离了 50 毫秒/秒左右。为什么会发生这种情况,我该如何预防?
global timerState
timerState = True
def pause():
timerLabel.after_cancel(tim)
timerState = False
timerButton.config(text="Play", command=countdown)
def countdown():
global t
global tim
if t == 0:
timer = "00:00"
timerLabel.config(text=timer)
return
if timerState == False:
return
mins = t / 60000
secs = t / 1000
secs = secs - int(mins) * 60
mills = t
mills = mills - int(secs) * 1000
if timerState == True:
timer = "{:02d}:{:02d}".format(int(mins),int(secs))
timerLabel.config(text=timer)
t -= 1
tim = timerLabel.after(1, countdown)
timerButton.config(text="Pause", command=pause)
解决方案
这就是它的设计工作方式。Tkinter 从来没有被设计成一个实时系统。Tkinter 在单个线程中运行其所有代码。如果时间已经过去并且 tkinter 正忙于做其他事情(运行一个函数,更新屏幕等),它必须在运行预定的函数之前完成它正在做的事情。
您运行的所有代码都after
需要时间。做数学需要时间,更新标签需要时间,甚至调用的行为也after
需要时间。当您将完成这些事情所需的所有时间加起来时,它很容易超过 1 毫秒。
推荐阅读
- java - Liberty Core:未找到 Spring Boot 上下文根
- java - 使用模拟测试的空服务响应
- javascript - jQuery 检查索引值的一部分
- php - 无法在 Laravel 中检索上传的图像文件的 URL
- ios - MFMailComposeViewController canSendMail 总是返回 false
- reactjs - 将多个字段值保存在状态反应中
- python-3.x - 如何读取子进程的输出而不将其打印在父进程的外壳中?
- c# - 我无法在任何计算机上安装该程序。“此 Windows 安装程序包有问题”
- windows - 如何批量重命名文件,包括数字和修改日期?
- python - How to Measure the difference between features in dataframe?