注意:以下代码是在 Python 3.5 中编写和测试的。例如,在调用super 时,可能需要进行一些小的更改。
documentation 对Widget.after 方法的描述如下:
after(delay_ms, callback=None, *args)
注册一个在给定时间后调用的警报回调。
调度函数
after 方法主要用于在给定延迟后安排函数调用。例如,以下代码安排在一秒后调用函数:
import tkinter as tk
def speak():
print("Hello world!")
root = tk.Tk()
root.after(1000, speak)
# Output
Hello world!
使函数定期运行
为了使函数定期运行,可以让它在自己的主体末尾调用自己。但是,after 是来自Widget 类的方法,因此需要一个小部件。因此,最好的选择通常是将调度函数放在扩展 Widget 的类中。
以下代码在控制台中每隔一秒打印一次"Hello world!"。
import tkinter as tk
class Foo(tk.Tk):
def periodically_speak(self):
print("Hello world!")
self.after(2000, self.periodically_speak)
foo = Foo()
foo.periodically_speak()
使用参数
可能希望将参数传递给定期运行的方法。为此,after 方法将回调后的每个参数解包为要传递给回调的参数。例如,root.after(1000, foo, a, b, c) 将安排对foo(a, b, c) 的呼叫。下面的例子展示了如何使用这个特性来确定函数的行为。
import tkinter as tk
class Foo(tk.Tk):
def periodically_speak(self, text):
print(text)
self.after(2000, self.periodically_speak, text)
foo = Foo()
foo.periodically_speak("Good night world!")
取消通话
after 方法返回一个字符串,对应于调用的 id。可以将其传递给after_cancel 方法,以取消已安排的调用。
以下示例将开始每秒打印"Hello world!",但在按下按钮时将停止。
import tkinter as tk
class Foo(tk.Tk):
def __init__(self):
super().__init__()
self.callId = None
self.button = tk.Button(self, text="Stop", command=self.stop)
self.button.pack()
def periodically_speak(self):
print("Hello world!")
self.callId = self.after(2000, self.periodically_speak)
def stop(self):
if self.callId is not None:
self.after_cancel(self.callId)
foo = Foo()
foo.periodically_speak()
旁注
应牢记以下几点。
-
after 方法不保证回调将在给定延迟之后*准确*被调用,但*至少*在它之后。因此,after 不应用于需要精度的地方。
- 使用
time.sleep 来安排或定期运行函数可能很诱人。在 GUI 上工作时必须避免这种情况,因为 `sleep` 会暂停当前线程,大部分时间都是主线程。例如,这可能会停止小部件的刷新,程序将停止响应。