我想了解如何最好地使用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秒后显示:
这意味着所有计数器都会更新。在这种情况下,.after()
适用于什么? (对不起,如果这不是正确的表达方式)
换句话说,<whatever object exists>.after(time, my_callback)
会起作用,因此将它绑定到根窗口只是一个约定?
答案 0 :(得分:2)
after
,Tkinter.Tk
,Tkinter.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
方法,因为:
正如您在帖子中所说,这是一种非常常见的做法。如果你打破这种伪约定,可能会让人感到困惑。
通常,在您明确关闭应用程序之前,根窗口对象不会消失。换句话说,它将永远存在。如果您使用子窗口小部件的after
方法(例如标签),则代码可能会破坏并在窗口小部件对象被销毁时引发AttributeError
。如果您的应用程序包含动态窗口小部件和/或窗口小部件,在满足特定条件后消失,则可能会发生这种情况。
这只是我的观点,但主窗口对象负责执行回调和管理事件似乎是正确的。毕竟,它代表了应用程序本身。然而,标签应该只是:标签。它不应该与管理应用程序有关。