我正在努力学习python、Tkinter和oop。下面是我在以下教程之后编写的代码effbot.org网站在
from Tkinter import Tk, Frame, Label
class Nexus(object):
"""Top level object which represents entire app"""
def __init__(self, main_window):
self.nexus_frame = Frame(main_window)
self.nexus_frame.pack()
self.label = Label(main_window, text="Tkinter")
self.label.pack()
def main():
main_window = Tk()
nexus_app = Nexus(main_window)
main_window.wm_title("Hello World Window")
width = main_window.winfo_screenwidth()
height = main_window.winfo_screenheight()
main_window.wm_minsize(width=width-100, height=height-100)
main_window.mainloop()
if __name__ == "__main__":
main()
这里首先创建一个顶层窗口,并将其作为参数传递给Nexus类,在这里我向该框架添加一个框架和一个标签。然后我在主函数中设置顶层窗口相对于当前屏幕大小的大小。在
我的问题是为什么顶层窗口是在main函数中创建的?
它不能在Nexus类本身的__init__
内创建吗?
如果主窗口是在Nexus类的__init__
内创建的,而mainloop()
在其中启动,会有什么不同?在
一旦
Tk.mainloop
被输入,将不再执行任何代码。取而代之的是Tk
事件循环(因此得名)。在这意味着,如果你,例如,做了这样的事情:
这样就永远不会执行print语句(或者至少在GUI运行时不会执行)。在
那么,考虑到这一点,为什么在构造函数中创建根窗口并执行主循环(即
__init__
语句)时会出现问题?好吧,有两个基本原因:这意味着构造函数永远不会返回,这是意外的。如果程序员看到这个:
^{pr2}$然后他或她将期望执行打印语句。通常,不会期望创建类的实例会导致无限循环(就像事件循环一样)。
与此相关的是第二个原因:不可能创建一个以上的
Nexus
实例,因为一旦创建了一个实例,Tk.mainloop
就会接管。同样,这是意料之外的:类是一种对象类型的描述,您通常希望能够实例化多个这样的对象。在现在,如果你写下:
然后您将在屏幕上看到两个
Nexus
窗口的副本。这是意料之中的,也是明智的。另一种选择是不会的。那么外卖信息是什么?在
当您处理GUI程序时,进入事件循环是您最不想做的事情。您的设置可能涉及到创建一个对象(如现在),也可能涉及创建多个对象(例如,一个复杂的GUI应用程序可能有两个或三个窗口)。在
因为我们希望能够在这两种情况下编写类似的代码,通常的方法是创建一次根窗口(即
Tk
对象),然后将其作为对需要了解它的任何类的引用传入。在相关问题 更多 >
编程相关推荐