8

我试图了解如何创建小部件。而且我发现上面三个函数被用于创建一个小部件,但我无法想出一个与另一个相比的区别和优势。尽管如此,我看过这个答案仍然让我感到困惑(而且它也没有说什么winfo_toplevel)。

这是我的代码。

from tkinter import *

root = Tk()
root.title("Root widget")
root.mainloop()

window = Toplevel()
window.title("Window widget")
window.mainloop()

在运行上面的代码时,“Root”小部件正在被创建。在关闭“根”时,会创建两个小部件,其中一个名为“窗口小部件”,另一个是不需要的。在关闭不需要的小部件时,“窗口小部件”也会被破坏。这里实际发生了什么以及如何克服?

另一个样本:

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() 之间的确切区别是什么。什么时候应该有效使用。寻找真正更好的理解。

4

1 回答 1

7

在运行上面的代码时,“Root”小部件正在被创建。在关闭“根”时,会创建两个小部件,其中一个名为“窗口小部件”,另一个是不需要的。在关闭不需要的小部件时,“窗口小部件”也会被破坏。这里实际发生了什么以及如何克服?

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

在第二部分,再次winfo_toplevel引用自动创建的Tk实例并以自动创建Tk的作为父级的方式创建其他子级,这在技术上应该是好的,但比创建相同 GUI 的标准方法更难维护为代码我' d 假设。


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

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

本质上,您正在尝试对方法使用不区分大小写的拼写,就好像它是诸如Toplevelor之类的类名Tk,这winfo_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_toplevelis 只是一个方法返回Toplevel一个小部件所在的 -like 父级的引用,作为父级是 aToplevel或 a的实例Tk

于 2018-01-16T11:02:06.617 回答