我正在尝试使用OOP方法理解一个程序,但这似乎并不顺利。
我可以按照下面的代码(我在网上找到)相当多,但我对 root
和my_gui
之间的关系有一些疑问 (在类定义下面找到)。
import tkinter as tk
class MyFirstGUI:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = tk.Label(master, text="This is our first GUI!")
self.label.pack()
self.greet_button = tk.Button(master, text="Greet", command=self.greet)
self.greet_button.pack()
def greet(self):
print("Greetings!")
root = tk.Tk()
my_gui = MyFirstGUI(root)
root.mainloop()
我知道init方法中的标签和按钮对象都进入主对象(它是根对象),但令我困惑的是在init方法之后区分my_gui
和root
已被执行。
my_gui
和。{
root
成为同一个东西,或者root
现在是其中的一个子集
my_gui
?my_gui
对象,是吗?self.master = master
到底在做什么?我想我真正想知道的是my_gui
和root
之间的关系。
答案 0 :(得分:2)
root
与my_gui
之间的唯一关系是my_gui
使用root
。否则它们只是引用两个不同对象的两个变量。
在类的init方法执行之后,my_gui和root是否成为同一个东西,或者root现在是my_gui的子集?
都不是。 root不是my_gui
的子集,它只是my_gui
知道的许多内容之一。它不是my_gui
的子集,my_gui
只是使用。
如果init函数执行后它们基本相同,则不需要“my_gui”对象,是吗?
它们基本上不一样。 my_gui
是MyFirstGUI
的实例,root
是Tk
的实例。它们是两个独立的东西,在这个具体的例子中,两者都是必需的。
“self.master = master”究竟在做什么?
它记住了传递给它的参数,以便稍后可以引用它。
答案 1 :(得分:2)
"对象和分配给它的tkinter对象有什么区别?"
我认为你的意思是这个部分:
root = tk.Tk()
my_gui = MyFirstGUI(root)
此处root
并未完全分配到某个对象,而是作为参数传递给一个对象。然后将该参数指定为该对象的属性。哪个 表示root
现在 是my_gui
的一个子集,就python层次而言。
my_gui
对象使用root
对象的方式首先将其指定为属性self.master
,然后创建小部件作为子对象。
"如果它们在init函数执行后基本相同,那么就不需要
my_gui
对象,是吗?"
它们不相同,它们是唯一类的实例。
您可以将MyFirstGUI
视为GUI的一个构造函数类。在上面的例子中,它正在为root
构建,但它也可以构建一些(Toplevel
)小部件root
以后可能有:
my_toplevel = tk.Toplevel(root)
my_gui2 = MyFirstGUI(my_toplevel)
它甚至可以为Label
和/或Button
当前拥有的root
窗口小部件构建,如果{{1},它们也是my_gui
的属性已删除行。
"
master.title(...)
到底在做什么?"
该行采用方法变量(self.master = master
)并将其作为属性分配给使用master
类创建的每个特定对象。 然后可用于在MyFirstGUI
中的所有子范围内进行修改/使用(并且其对象MyFirstGUI
的范围可用)。它的一个使用示例是my_gui
中有一个使用以下行创建的标签:
__init__
虽然在另一种方法下无法实现,例如self.label = tk.Label(master, text="This is our first GUI!")
,如果 greet,
不存在。如同:
self.master = master
并且调用def greet(self):
print("Greetings!")
self.label2 = tk.Label(master, text="Greetings!")
self.label2.pack()
时会返回my_gui.greet()
错误:
NameError: name 'master' is not defined
再次调用def greet(self):
print("Greetings!")
self.label2 = tk.Label(self.master, text="Greetings!")
self.label2.pack()
可以完美地按预期工作。