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

时间:2016-03-25 05:50:00

标签: 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没有自我。和标签和条目有它。

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

3 个答案:

答案 0 :(得分:4)

<强>更新

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

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

方法1

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

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

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时它会& #39;使用窗口对象的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 1}}(窗口对象)作为父母而不是root。因为当使用grid(row=0, column=0)作为父项,在单选按钮上调用int get_grid(int i, int j) { if (i>=0 && i<SIZE) return grid[i][j]; return 0; } 时,它们将使用窗口对象(框架)正在使用的相同行/列。

答案 1 :(得分:2)

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

由于appWindow的实例且WindowFrame的子类,因此除非appapp,否则此小部件中的所有内容都将不可见可见。因此,解决方案的第二部分是使app = Window(root) app.pack(fill="both", expand=True) 可见。你可以随心所欲地做到这一点。在这种特殊情况下,由于它是根窗口中唯一的小部件,我会使用pack:

var owl = $('.owl-slider').owlCarousel({your options});
var item = '<div class=" item...">your new div</div>';
owl.data('owlCarousel').addItem(item); 
owl.reinit(); 

答案 2 :(得分:1)

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