什么.after()适用于什么?

时间:2014-07-23 16:28:13

标签: python tkinter

我想了解如何最好地使用after(),即将其绑定的内容。为了测试几个场景,我编写了三个显示秒数的简单计数器:

  • clock1:框架中的标签(本身是根窗口的子框架),绑定到框架
  • clock2:与上面相同的框架中的标签,绑定到根
  • clock3:root中的标签,绑定到root

实际代码:

import Tkinter as tk

class App():
    def __init__(self):
        self.counter1 = 0
        self.counter2 = 100
        self.counter3 = 1000
        self.root = tk.Tk()
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        self.label1 = tk.Label(self.frame, text="clock1")
        self.label1.pack()
        self.label2 = tk.Label(self.frame, text="clock2")
        self.label2.pack()
        self.label3 = tk.Label(self.root, text="clock3")
        self.label3.pack()

    def clock1(self):
        self.counter1 += 1
        text = "hello from clock1: {}".format(self.counter1)
        self.label1.configure(text=text)
        self.frame.after(1000, self.clock1)

    def clock2(self):
        self.counter2 += 1
        text = "hello from clock2: {}".format(self.counter2)
        self.label2.configure(text=text)
        self.root.after(1000, self.clock2)

    def clock3(self):
        self.counter3 += 1
        text = "hello from clock3: {}".format(self.counter3)
        self.label3.configure(text=text)
        self.root.after(1000, self.clock3)

a = App()
a.clock1()
a.clock2()
a.clock3()
a.root.mainloop()

此代码在运行时会在18秒后显示:

enter image description here

这意味着所有计数器都会更新。在这种情况下,.after()适用于什么? (对不起,如果这不是正确的表达方式)

换句话说,<whatever object exists>.after(time, my_callback)会起作用,因此将它绑定到根窗口只是一个约定?

1 个答案:

答案 0 :(得分:2)

afterTkinter.TkTkinter.Label等的Tkinter.Frame方法完全相同:

>>> import Tkinter
>>> Tkinter.Tk.after is Tkinter.Frame.after
True
>>> Tkinter.Label.after is Tkinter.Tk.after
True
>>> Tkinter.Frame.after is Tkinter.Label.after
True
>>>

这是因为after所有 Tkinter小部件上的basic widget method。因此,您可以随意调用它,并始终获得相同的效果。

那就是说,我认为最好只在根窗口对象(主after实例)上调用Tkinter.Tk方法,因为:

  1. 正如您在帖子中所说,这是一种非常常见的做法。如果你打破这种伪约定,可能会让人感到困惑。

  2. 通常,在您明确关闭应用程序之前,根窗口对象不会消失。换句话说,它将永远存在。如果您使用子窗口小部件的after方法(例如标签),则代码可能会破坏并在窗口小部件对象被销毁时引发AttributeError。如果您的应用程序包含动态窗口小部件和/或窗口小部件,在满足特定条件后消失,则可能会发生这种情况。

  3. 这只是我的观点,但主窗口对象负责执行回调和管理事件似乎是正确的。毕竟,它代表了应用程序本身。然而,标签应该只是:标签。它不应该与管理应用程序有关。