繁体   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