簡體   English   中英

使用框架和網格的 tkinter gui 布局

[英]tkinter gui layout using frames and grid

我的gui布局

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 這會導致您認為進入頂部框架的每個小部件實際上進入根窗口。

解決方案概述

作為一般經驗法則,您永遠不應該在創建小部件的同一語句中調用gridpackplace 部分是因為您正在經歷這種確切的行為,但也因為我認為隨着時間的推移,它會使您的代碼更難編寫和維護。

小部件創建和小部件布局是兩件不同的事情。 根據我的經驗,當您將布局命令組合在一起時,布局問題更容易調試。

此外,您在使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM