Tk()、Toplevel() 和 winfo_toplevel().它们之间的区别以及如何以及何时有效使用?



我正在尝试了解如何创建小部件。我发现上面三个函数被用于创建小部件,但我无法想出一个函数的区别和优势。尽管如此,我还是看了一下这个仍然让我感到困惑的答案(而且它也没有说任何关于winfo_toplevel的事情)。

这是我的代码。

from tkinter import *
root = Tk()
root.title("Root widget")
root.mainloop()
window = Toplevel()
window.title("Window widget")
window.mainloop()

在运行上面的代码时,正在创建"根"小部件。在关闭"根"时,将创建两个小部件,其中一个标题为"窗口小部件",另一个标题为"窗口小部件"。在关闭不需要的小部件时,"窗口小部件"也被销毁。 这里到底发生了什么,如何克服?

另一个示例:

class ldo(Frame):
def __init__(self, master = None):
Frame.__init__(self,master)
self.grid()
self.appOutline()
def appOutline(self):
top = self.winfo_toplevel()
self.menuBar = Menu(top)
top["menu"] = self.menuBar
self.subMenu1 = Menu(self.menuBar)
self.menuBar.add_cascade(label = "File", menu = self.subMenu1)
app = ldo()
app.master.title("Sample UI")
app.mainloop()

另一方面,此代码使用的小部件看起来完全正常的winfo_toplevel()。在这里,我的假设是,Frame扮演着创建小部件的角色,winfo_toplevel()是其他tkinter项目的增强工具。但想知道它实际上做了什么。

但是,下面的代码片段不起作用:

winf = winfo_Toplevel()
winf.title("Winfo Widget")
winf.mainloop()

并返回这样的错误:

winf = winfo_Toplevel()
NameError: name 'winfo_Toplevel' is not defined

Tk()、Toplevel() 和 winfo_Toplevel() 之间的确切区别是什么?应该在何时有效使用。寻找真正的更好的理解。

在运行上面的代码时,正在创建"根"小部件。在关闭"根"时,将创建两个小部件,其中一个标题为"窗口小部件"和 其他是不需要的。在关闭不需要的小部件时,"窗口小部件"是 也被摧毁了。这里实际发生了什么以及如何 克服?

当您在没有实际Tk()实例的情况下创建任何小部件时,会自动创建一个Tk()实例,从而在第一个代码片段的第二部分运行时产生不需要的类似顶级的小部件。此外,当创建小部件时没有master选项时,假定该实例是Tk实例之一的子实例,在上述情况下,只有一个,那就是自动创建的实例。当父级被销毁时,它下的所有小部件也会被销毁,因此当您关闭作为Tk实例的不需要的小部件时,Toplevel实例也会被销毁,因为它的父实例被销毁。

在第二部分,winfo_toplevel再次引用自动创建的Tk实例,并使用自动创建的Tk作为父实例创建其他子实例,这在技术上应该没问题,但作为代码更难维护,而不是创建相同 GUI 的标准方法我假设。


winf = winfo_Toplevel()
winf.title("Winfo Widget")
winf.mainloop()

在上面的代码片段中,除非导入或以其他方式定义winfo_Toplevel否则没有意义,首先,它与winfo_toplevel不同,因为python区分大小写。其次,即使python不区分大小写,它仍然会抛出错误,因为它是一个方法,并且缺少第一个位置参数,这是定义winfo_toplevel方法的类的对象实例。

本质上,您尝试使用不区分大小写的方法拼写,就好像它是一个类名,例如ToplevelTkwinfo_toplevel几乎无关。


检查以下代码:

import tkinter as tk
root = tk.Tk()
root.title("This is the actual Tk instance, root")
toplevel = tk.Toplevel(root)
toplevel.title("This is a Toplevel, whose parent is root"),
r_lbl = tk.Label(text="""This label is a children to the default master, 
as it lacks the first positional argument for an explicit parent 
assignment.""")
r_lbl2 = tk.Label(r_lbl.winfo_toplevel(), text="""This label checks who the
toplevel parent for r_lbl is, and then selects that parent as a parent
to itself.""")
r_lbl3 = tk.Label(root, text="""This label will appear on root, as it's
explicitly passed as the first positional argument, which is the parent,
as root.""")
t_lbl = tk.Label(toplevel, text="""This label will appear on toplevel, as it's
explicitly passed as the first positional argument, which is the parent,
as toplevel.""")
t_lbl2 = tk.Label(t_lbl.winfo_toplevel(), text="""This label checks who the
toplevel parent for t_lbl is, and then selects that parent as a parent
to itself.""")
r_lbl.pack()
r_lbl2.pack()
r_lbl3.pack()
t_lbl.pack()
t_lbl2.pack()
root.mainloop()

总之,Tk,虽然是一个Toplevel小部件,但它也是线程中运行的整个 GUI 的 tcl 解释器。可以有多个实例,不鼓励这样做,因为通常有多个实例是不合理的,但也必须至少存在一个实例才能拥有 GUI。

Toplevel可以被认为是Tk实例的唯一可视部分,当需要多个类似窗口的小部件时,可以使用它。

最后,winfo_toplevel只是一个方法,返回小部件所在的类似Toplevel父项的引用,父项是ToplevelTk的实例。

相关内容

最新更新