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

标签 python tkinter

代码如下:

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()

这是输出:

enter image description here

我的标签和条目都没有显示。

我发现 Radiobutton 没有 self 。 Label 和 Entry 都有。

但是,我不知道为什么会造成这样的结果。

最佳答案

更新

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

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

方法一

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 小部件添加到 self (Window 对象) ,因此在它们上调用 grid 时,它使用 window 对象的 grid 布局。但是窗口对象本身并没有添加到 root (Tk),所以基本上 window 对象和它附加的小部件根本不会显示。

然而,Radiobutton 实例附加到 root,因此对它们调用 grid 会将它们添加到 的布局管理器root (Tk),这就是他们展示的原因。

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

方法二

将窗口对象本身添加到 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(窗口对象)作为它们的 parent 而不是 root。因为当使用 root 作为父级时,在单选按钮上调用 grid(row=0, column=0) 时,它们将使用与窗口对象相同的行/列(框架)正在使用。

关于python - 如何在根 TopLevel 下的 Python Tkinter 框架中布局小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36214749/

相关文章:

python pandas 总结标称变量(计数)

python argparse : arg with no flag

python - Python Tkinter程序崩溃时忘记了()

尝试使用 matplotlib 保存图像时 Python tkinter 卡住

python - 嵌套的 django 模板

python - 当我将 PyQt4 中的 QWebView 放入函数中时,它不会打开

python - 开始使用 Keras 进行机器学习

Python 滚动文本模块

python - 为什么 Entry.get() 落后一键?

python - Tkinter:OptionMenu 对象菜单不适用于 highlightthickness=0