繁体   English   中英

如何在根TopLevel下的Python Tkinter框架中布局窗口小部件

[英]How to layout widgets in a Python Tkinter frame under a root TopLevel

这是代码:

class Window(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.master = master
        self.init_window()
    def init_window(self):
        self.master.title('GUI')

        row = 0
        self.s_date_label = Label(self, text = 'Start Date: ')
        self.s_date_label.grid(row=row, column=0, sticky = W)
        self.start_date = Entry(self, bd=1)
        self.start_date.grid(row=row, column=1, sticky = W)
        self.s_date_label2 = Label(self, text = 'example: 20160101')
        self.s_date_label2.grid(row=row, column=2, sticky = W)

        self.datetype_var = IntVar()
        R1 = Radiobutton(root, text="20160101", variable=self.datetype_var, value=8)
        R1.grid(row=row, column=1, sticky = W)
        R1.select()
        R2 = Radiobutton(root, text="201601", variable=self.datetype_var, value=6)
        R2.grid(row=row, column=2, sticky = W)
        R3 = Radiobutton(root, text="2016", variable=self.datetype_var, value=4)
        R3.grid(row=row, column=3, sticky = W)

root = Tk()
root.geometry('600x400')

app = Window(root)

root.mainloop()

这是输出:

在此输入图像描述

我的标签和条目都没有出现。

我发现Radiobutton没有自我。 和标签和条目有它。

但是,我不知道为什么会导致结果。

更新

我提出了两种方法来解决这个问题。 第一个是使用root Tk对象作为所有小部件的父对象; 其次是将窗口小部件添加到Window ,并将Window对象添加到root的布局管理器。 正如Bryan Oakley在评论中(正确地)提到的那样,第一种方法并不是那么好(尽管它有效,但仍然如此)。 所以我建议使用第二种方法(下面讨论),即:

确保所有小部件( RadiobuttonLabelEntry等)都使用Window对象(由self引用)作为父对象,然后将窗口实例添加到root的布局管理器中。 init_window调用中,或在创建对象之后。

方法1

Window下的小部件应该使用self作为父级(保留层次结构),而Window本身应该添加到master布局管理器中。 这样所有小部件都将正确显示

在将小部件添加到布局(在本例中为grid几何)时,您应该已经传递了Tk对象(由root引用)。

from Tkinter import *

class Window(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.master = master
        self.init_window()

    def init_window(self):
        self.master.title('GUI')

        row = 0
        self.s_date_label = Label(self.master, text = 'Start Date: ')
        self.s_date_label.grid(row=row, column=0, sticky = W)
        self.start_date = Entry(self.master, bd=1)
        self.start_date.grid(row=row, column=1, sticky = W)
        self.s_date_label2 = Label(self.master, text = 'example: 20160101')
        self.s_date_label2.grid(row=row, column=2, sticky = W)

        self.datetype_var = IntVar()
        R1 = Radiobutton(self.master, text="20160101", variable=self.datetype_var, value=8)
        R1.grid(row=row, column=1, sticky = W)
        R1.select()
        R2 = Radiobutton(self.master, text="201601", variable=self.datetype_var, value=6)
        R2.grid(row=row, column=2, sticky = W)
        R3 = Radiobutton(self.master, text="2016", variable=self.datetype_var, value=4)
        R3.grid(row=row, column=3, sticky = W)

root = Tk()
root.geometry('600x400')

app = Window(root)

root.mainloop()

请注意,父(传递给LabelEntry构造函数的第一个参数)从self更改为self.master

Radiobutton的父级也从root更改为self.master ,因为root是对全局变量的引用,而不是Window对象的实际父级。

更新(描述)

问题的代码是将LabelEntry小部件添加到selfWindow对象),因此当在它们上调用grid时,它使用窗口对象grid布局。 但是窗口对象本身并未添加到root (Tk) ,因此基本上window对象及其附加的窗口小部件根本不会显示。

然而, Radiobutton实例被附加到root ,因此在它们上面调用grid会将它们添加到root (Tk)布局管理器中,这就是它们显示的原因。

对此的一个解决方法是继续使用root作为所有窗口小部件的父窗口,这会导致窗口对象像数据容器,但不是UI上的窗口小部件。

方法2

将窗口对象本身添加到root的布局管理器。 像这样的东西:

#all the code is the same as the question
# ...
app = Window(root)
app.grid(row=0, column=0, sticky=NW)
# the rest of the code

但请记住,如果你想使用这种方法(使用窗口对象作为Widget容器),那么我再次建议所有Radiobutton使用self (窗口对象)作为他们的父母而不是root 因为当使用root作为父节点时,在单选按钮上调用grid(row=0, column=0) ,它们将使用窗口对象(框架)正在使用的相同行/列。

appWindow一个实例。 Window是一个Frame init_window创建的小部件有时会将self作为父级,有时则是root 你需要解决的第一件事情是,它们都需要有家长self 这种设计的意义,你毫无疑问是从某个地方复制过来的,这个类中的所有东西都应该包含在这个框架中。

由于app是一个实例WindowWindow是的子类Frame ,在这个小部件去将是无形的,除非一切app是可见的。 因此,解决方案的第二部分是使app可见。 你可以随心所欲地做到这一点。 在这种特殊情况下,由于它是根窗口中唯一的小部件,我会使用pack:

app = Window(root)
app.pack(fill="both", expand=True)

你正在制作标签并输入他们自己的父母,而不是开始他们自己的事件循环。 而不是self ,尝试将其父级更改为root

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM