之后的Tkinter幸免于时钟倒带

Ore*_*ren 9 python windows tkinter

我注意到在我的Tkinter版本中,after()调用无法在系统时钟倒带后幸存。

如果调用after(x,func),并且倒带了系统时钟,则仅在时钟返回倒带之前的时间+ x毫秒之后,才调用func

我认为这是因为Tkinter使用系统时钟而不是“ time.clock”(程序运行的时间)。

我只在Windows上测试过它,也许是因为我有旧版本的Tkinter。我希望我的应用程序能够在通过网络同步其时钟的计算机上工作...

有没有人有一个简单的解决方案?

A. *_*das 5

不幸的是,Tkinter和Tcl解释器都没有直接解决您的问题的方法。该after(ms, func)方法基于同名的Tcl命令,该命令基于当前系统时间加上作为参数传递的毫秒数来创建内部计时器。

如果您感到好奇,可以直接从Tcl / Tk源代码中检出:

Tcl_GetTime(&wakeup);
wakeup.sec += (long)(ms / 1000);
wakeup.usec += ((long)(ms % 1000)) * 1000;
if (wakeup.usec > 1000000) {
    wakeup.sec++;
    wakeup.usec -= 1000000;
}
afterPtr->token = TclCreateAbsoluteTimerHandler(&wakeup,
    AfterProc, afterPtr);
Run Code Online (Sandbox Code Playgroud)

鉴于此限制,我将采用纯Python方法,例如使用Timer

import time
import threading
import tkinter as tk

root = tk.Tk()

def say_hi():
    print(time.perf_counter(), "-", "Hi after 30sec!")
    root.destroy()

print(time.perf_counter(), "-", "Waiting 30sec")
threading.Timer(30, say_hi).start()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

它还具有在单独的线程上运行的优点,不仅可以防止在计时器间隔内阻塞GUI,还可以防止在执行回调函数时阻塞GUI。