如何使用 after 方法使回调定期运行? [英] How to use the after method to make a callback run periodically?

查看:32
本文介绍了如何使用 after 方法使回调定期运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

With tkinter, how can I use the after method to make a function run periodically?

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

For instance, I have a speak function that only prints something in the console:

def speak():
    print("Hello, world!")

如何使用after方法每秒调用speak函数?

How can I use the after method to call the speak function every second?

推荐答案

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

Note: the following code is written and tested in Python 3.5. Minor changes might be needed, for instance, when calling super.

文档 描述了 Widget.after 方法如下:

The documentation describes the Widget.after method as follows:

after(delay_ms, callback=None, *args)

注册在给定时间后调用的闹钟回调.

Registers an alarm callback that is called after a given time.


安排函数

after 方法主要用于在给定的延迟之后安排函数调用.例如,下面的代码安排一秒后对函数的调用:

The after method is primarily used to schedule a function call after a given delay. For instance, the following code schedules a call to a function after one second:

import tkinter as tk

def speak():
    print("Hello world!")

root = tk.Tk()
root.after(1000, speak)

# Output
Hello world!


使函数定期运行

为了让一个函数周期性地运行,可以让它在自己的函数体的末尾调用自己.但是,after 是来自 Widget 类的方法,因此需要一个小部件.因此,最好的选择通常是将调度函数放在扩展 Widget 的类中.

In order to make a function run periodically, one can make it call itself at the end of its own body. However, after is a method from the Widget class, so a widget is needed. Therefore, the best choice is generally to put the scheduled function inside of a class extending Widget.

以下代码每隔一秒在控制台打印一次"Hello world!".

The following code prints "Hello world!" every other second in the console.

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) 的调用.以下示例展示了如何使用此功能来确定函数的行为.

One might want to pass parameters to a method that runs periodically. For this purpose, the after method unpacks every parameter after the callback as the parameters to pass to the callback. For instance, root.after(1000, foo, a, b, c) will schedule a call to foo(a, b, c). The following example shows a use of this feature to determine the behaviour of the function.

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 方法,以取消预定的调用.

The after methods returns a string, that corresponds to the call's id. It can be passed to the after_cancel method, in order to cancel a call that was scheduled.

以下示例将开始每秒打印 "Hello world!",但在按下按钮时停止打印.

The following example will start printing "Hello world!" every second, but will stop when pressing the button.

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` 将暂停当前线程,该线程大部分时间是主线程.例如,这可能会停止小部件的刷新,程序将停止响应.
  • The after method does not guarantee that the callback will be called *exactly* after the given delay, but *at least* after it. As a consequence, after should not be used where precision is required.
  • It might be tempting to use time.sleep in order to schedule or periodically run a function. This must be avoided when working on a GUI, because `sleep` will pause the current thread, which most of the time is the main thread. For example, this could halt the refresh of the widgets, the program would stop responding.

这篇关于如何使用 after 方法使回调定期运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆