[英]tkinter gui layout using frames and grid
我的gui布局
看起來幾乎不像我期望的那樣
所以我假設有一些我不明白的基礎知識。
我假設框架包含它們自己的“網格空間”(行、列),但我看到的行為並不支持這一點,而且我對讓頂部框架按照我想要的方式工作感到茫然。 我的標簽應該在 L 到 R 的同一行上,在跨越整個框架的“框架標簽”下——除非它們沒有。 我希望實際看起來更像目標 jpg,我想使用網格來做到這一點。
您只能看到綠框右側的輸入字段之一。 為什么要去那里?
from Tkinter import *
root = Tk()
root.title('Model Definition')
root.resizable(width=FALSE, height=FALSE)
root.geometry('{}x{}'.format(460, 350))
top_frame = Frame(root, bg='cyan', width = 450, height=50, pady=3).grid(row=0, columnspan=3)
Label(top_frame, text = 'Model Dimensions').grid(row = 0, columnspan = 3)
Label(top_frame, text = 'Width:').grid(row = 1, column = 0)
Label(top_frame, text = 'Length:').grid(row = 1, column = 2)
entry_W = Entry(top_frame).grid(row = 1, column = 1)
entry_L = Entry(top_frame).grid(row = 1, column = 3)
#Label(top_frame, text = '').grid(row = 2, column = 2)
center = Frame(root, bg='gray2', width=50, height=40, padx=3, pady=3).grid(row=1, columnspan=3)
ctr_left = Frame(center, bg='blue', width=100, height=190).grid(column = 0, row = 1, rowspan = 2)
ctr_mid = Frame(center, bg='yellow', width=250, height=190, padx=3, pady=3).grid(column = 1, row=1, rowspan=2)
ctr_right = Frame(center, bg='green', width=100, height=190, padx=3, pady=3).grid(column = 2, row=1, rowspan=2)
btm_frame = Frame(root, bg='white', width = 450, height = 45, pady=3).grid(row = 3, columnspan = 3)
btm_frame2 = Frame(root, bg='lavender', width = 450, height = 60, pady=3).grid(row = 4, columnspan = 3)
root.mainloop()
具體來說,我的標簽和 Entry 小部件去了哪里,以及如何讓它們看起來更像目標(頂部框架,其余部分用於稍后)。
我假設框架包含自己的“網格空間”
這是一個正確的假設。
您只能看到綠框右側的輸入字段之一。 為什么要去那里?
問題從這里開始:
top_frame = Frame(root, ...).grid(row=0, ...)
在 python 中, x = y().z()
將始終將x
設置為.z()
的結果。 在top_frame = Frame(...).grid(...)
, grid(...)
總是返回None
所以top_frame
將是None
。 這會導致您認為進入頂部框架的每個小部件實際上進入根窗口。
作為一般經驗法則,您永遠不應該在創建小部件的同一語句中調用grid
、 pack
或place
。 部分是因為您正在經歷這種確切的行為,但也因為我認為隨着時間的推移,它會使您的代碼更難編寫和維護。
小部件創建和小部件布局是兩件不同的事情。 根據我的經驗,當您將布局命令組合在一起時,布局問題更容易調試。
此外,您在使用grid
時應該保持一致,並始終以相同的順序放置選項,以便您可以更輕松地可視化布局。 最后,在使用grid
您應該養成始終指定sticky
選項的習慣,並始終為每個包含框架中的一行和一列賦予非零權重。
以下是我將如何編寫您的代碼。 它更長,但更容易理解。
from Tkinter import *
root = Tk()
root.title('Model Definition')
root.geometry('{}x{}'.format(460, 350))
# create all of the main containers
top_frame = Frame(root, bg='cyan', width=450, height=50, pady=3)
center = Frame(root, bg='gray2', width=50, height=40, padx=3, pady=3)
btm_frame = Frame(root, bg='white', width=450, height=45, pady=3)
btm_frame2 = Frame(root, bg='lavender', width=450, height=60, pady=3)
# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
top_frame.grid(row=0, sticky="ew")
center.grid(row=1, sticky="nsew")
btm_frame.grid(row=3, sticky="ew")
btm_frame2.grid(row=4, sticky="ew")
# create the widgets for the top frame
model_label = Label(top_frame, text='Model Dimensions')
width_label = Label(top_frame, text='Width:')
length_label = Label(top_frame, text='Length:')
entry_W = Entry(top_frame, background="pink")
entry_L = Entry(top_frame, background="orange")
# layout the widgets in the top frame
model_label.grid(row=0, columnspan=3)
width_label.grid(row=1, column=0)
length_label.grid(row=1, column=2)
entry_W.grid(row=1, column=1)
entry_L.grid(row=1, column=3)
# create the center widgets
center.grid_rowconfigure(0, weight=1)
center.grid_columnconfigure(1, weight=1)
ctr_left = Frame(center, bg='blue', width=100, height=190)
ctr_mid = Frame(center, bg='yellow', width=250, height=190, padx=3, pady=3)
ctr_right = Frame(center, bg='green', width=100, height=190, padx=3, pady=3)
ctr_left.grid(row=0, column=0, sticky="ns")
ctr_mid.grid(row=0, column=1, sticky="nsew")
ctr_right.grid(row=0, column=2, sticky="ns")
root.mainloop()
variable = Widget(...).grid()
將None
分配給變量,因為grid()
/ pack()
/ place()
返回None
用
variable = Widget(...)
variable.grid() # .pack() .place()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.