Python 如何使用after方法定期运行回调?

Python 如何使用after方法定期运行回调?,python,tkinter,Python,Tkinter,使用tkinter,如何使用after方法定期运行函数 例如,我有一个speak函数,它只在控制台中打印一些内容: def speak(): print("Hello, world!") 如何使用after方法每秒调用speak函数?注意:以下代码是用Python 3.5编写和测试的。例如,在调用super时,可能需要进行一些小的更改 描述了小部件。after方法如下: 之后(延迟毫秒,回调=无,*args) 注册在给定时间后调用的报警回调 安排功能 after方法主要用于在给定延迟

使用tkinter,如何使用
after
方法定期运行函数

例如,我有一个
speak
函数,它只在控制台中打印一些内容:

def speak():
    print("Hello, world!")
如何使用
after
方法每秒调用
speak
函数?

注意:以下代码是用Python 3.5编写和测试的。例如,在调用
super
时,可能需要进行一些小的更改

描述了
小部件。after
方法如下:

之后(延迟毫秒,回调=无,*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\u 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
    方法不能保证在给定延迟之后调用回调,但至少在给定延迟之后调用。因此,在需要精度的情况下,不应使用之后的
  • 使用
    time.sleep
    来计划或定期运行函数可能会很诱人。在GUI上工作时必须避免这种情况,因为“sleep”将暂停当前线程,而当前线程大部分时间是主线程。例如,这可能会停止小部件的刷新,程序将停止响应

此问题旨在规范tkinter中与
之后的
方法相关的问题。请检查下面随附的答案。与该主题相关的几乎不规范的问题的例子:,这个问题已经被问过并回答过多次。与其创建一个新的问题,为什么不编辑一个现有的答案,使之更规范?@BryanOakley好吧,我想这样做,但这些问题不太规范,通常与一个精确的问题相关,而该问题不适合编辑。所以,我决定写一个直截了当的问题。你的第一个答案不是很规范。您正在使用lambda,而lambda是不必要的,并且可能具有误导性。初学者可能会抓住第一个例子,并认为这就是您在
@BryanOakley Fair point之后应该如何使用
。我们中的一些熟悉Tkinter的人打算在接下来的几天里看看这对Q+A组合,并提出建设性的批评,使其达到最新水平。@BryanOakley你说得对,我编辑了这一点。正如PM 2Ring所说,请随意编辑这篇文章,我只想让它有所帮助:)