簡體   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