python - 如何在 tkinter 中巧妙地创建带有可调整大小的小部件的可调整大小的窗口?
问题描述
所以我正在使用 tkinter 来制作我的程序,经过很多麻烦,我得到了一些可调整大小的东西,这是我使用过的一个片段:
CR = tk.Checkbutton(self, text="Creativity", variable=CRval)
CR.place(relwidth=0.18, relheight=0.05, relx=0.68, rely=0.83, anchor="w")
正如您在下面看到的,复选框不在一行中,当我展开窗口时,它会更远:
我花了很长时间才让它们对齐,实际上不应该。我喜欢使用.grid()
,但我似乎找不到使用相对距离或设置网格大小的方法。
这部分窗口的完整代码如下 - 请注意,我每次都必须更改几乎所有内容的相对大小:
import tkinter as tk
self = tk.Tk()
KLval = tk.BooleanVar()
KL = tk.Checkbutton(self, text="Knots and Lashings", variable=KLval)
KL.place(relwidth=0.2, relheight=0.05, relx=0.03, rely=0.77, anchor="w")
SUval = tk.BooleanVar()
SU = tk.Checkbutton(self, text="Sense of Urgency", variable=SUval)
SU.place(relwidth=0.2, relheight=0.05, relx=0.023, rely=0.83, anchor="w")
FCval = tk.BooleanVar()
FC = tk.Checkbutton(self, text="Fieldcraft", variable=FCval)
FC.place(relwidth=0.15, relheight=0.05, relx=0.015, rely=0.89, anchor="w")
STval = tk.BooleanVar()
ST = tk.Checkbutton(self, text="Stealth", variable=STval)
ST.place(relwidth=0.1, relheight=0.05, relx=0.028, rely=0.95, anchor="w")
PLval = tk.BooleanVar()
PL = tk.Checkbutton(self, text="Planning", variable=PLval)
PL.place(relwidth=0.18, relheight=0.05, relx=0.25, rely=0.77, anchor="w")
RAval = tk.BooleanVar()
RA = tk.Checkbutton(self, text="Radios", variable=RAval)
RA.place(relwidth=0.18, relheight=0.05, relx=0.242, rely=0.83, anchor="w")
COval = tk.BooleanVar()
CO = tk.Checkbutton(self, text="Communication", variable=COval)
CO.place(relwidth=0.18, relheight=0.05, relx=0.28, rely=0.89, anchor="w")
SGval = tk.BooleanVar()
SG = tk.Checkbutton(self, text="Strategy", variable=SGval)
SG.place(relwidth=0.18, relheight=0.05, relx=0.249, rely=0.95, anchor="w")
PSval = tk.BooleanVar()
PS = tk.Checkbutton(self, text="Problem Solving", variable=PSval)
PS.place(relwidth=0.2, relheight=0.05, relx=0.47, rely=0.71, anchor="w")
DEval = tk.BooleanVar()
DE = tk.Checkbutton(self, text="Decoding", variable=DEval)
DE.place(relwidth=0.18, relheight=0.05, relx=0.448, rely=0.77, anchor="w")
FAval = tk.BooleanVar()
FA = tk.Checkbutton(self, text="First Aid", variable=FAval)
FA.place(relwidth=0.18, relheight=0.05, relx=0.444, rely=0.83, anchor="w")
PRval = tk.BooleanVar()
PR = tk.Checkbutton(self, text="Prioritising", variable=PRval)
PR.place(relwidth=0.18, relheight=0.05, relx=0.459, rely=0.89, anchor="w")
DMval = tk.BooleanVar()
DM = tk.Checkbutton(self, text="Decision Making", variable=DMval)
DM.place(relwidth=0.18, relheight=0.05, relx=0.478, rely=0.95, anchor="w")
REval = tk.BooleanVar()
RE = tk.Checkbutton(self, text="Re-Evaluation", variable=REval)
RE.place(relwidth=0.18, relheight=0.05, relx=0.7, rely=0.71, anchor="w")
MCval = tk.BooleanVar()
MC = tk.Checkbutton(self, text="Management and Control", variable=MCval)
MC.place(relwidth=0.3, relheight=0.05, relx=0.686, rely=0.77, anchor="w")
CRval = tk.BooleanVar()
CR = tk.Checkbutton(self, text="Creativity", variable=CRval)
CR.place(relwidth=0.18, relheight=0.05, relx=0.68, rely=0.83, anchor="w")
CKval = tk.BooleanVar()
CK = tk.Checkbutton(self, text="Core Knowledge", variable=CKval)
CK.place(relwidth=0.18, relheight=0.05, relx=0.71, rely=0.89, anchor="w")
self.geometry("650x400+400+50")
self.minsize(650, 400)
self.mainloop()
解决方案
解决方案是使用grid
或pack
——它们是专门为创建响应式用户界面而设计的。place
如果您完全关心响应能力,则很少是正确的选择。
如果您正在创建一个网格(即:按行和列排列)grid
是正确的选择。您可以使用 将内容排列在行和列中pack
,但需要一些额外的工作来模拟列。
此外,鉴于您的特定代码的性质,您应该认真考虑在循环中创建这些检查按钮并使用数据结构来保存对小部件和变量的引用。你这里的代码的问题是它不可读、难以维护并且难以可视化。
例如,您可以将缩写和标签保存在一组元组中,如下所示:
options = (
("KL", "Knots and Lashings"),
("SU", "Sense of Urgency"),
("FC", "Fieldcraft"),
("ST", "Stealth"),
("PL", "Planning"),
("RA", "Radios"),
("CO", "Communication"),
("SG", "Strategy"),
("PS", "Problem Solving"),
("DE", "Decoding"),
("FA", "First Aid"),
("PR", "Prioritising"),
("DM", "Decision Making"),
("RE", "Re-Evaluation"),
("MC", "Management and Control"),
("CR", "Creativity"),
("CK", "Core Knowledge")
)
然后,您可以使用缩写引用小部件。您可以为grid
每个小部件调用一次:
checkbuttons['PS'].grid(row=1, column=2, sticky="w")
checkbuttons['RE'].grid(row=1, column=3, sticky="w")
checkbuttons['KL'].grid(row=2, column=0, sticky="w")
...
或者,使用另一个循环。例如:
layout = (
(None, None, "PS", "RE"),
("KL", "PL", "DE", "MC"),
("SU", "RA", "FA", "CR"),
("FC", "CO", "PR", "CK"),
("ST", "SG", "DM", None),
)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure((0,1,2,3), weight=1)
for row, columns in enumerate(layout):
for column, key in enumerate(columns):
if key is not None:
checkbuttons[key].grid(row=row+1, column=column, sticky="w")
窗口现在完全响应。此外,添加更多选项或重新排列选项的顺序也很简单。这是原始尺寸:
这是窗户被拉开的情况:
推荐阅读
- mysql - 安装后没有 MySQL 应用程序
- sql - 为什么我的查询在 Visual Studio 2010 报表生成器中不起作用
- python - 如何在调用函数时强制命名函数的必需参数,而不给参数提供默认值?
- python - 以某个字符结尾的正则表达式应避免在此之前多次出现该字符
- reactjs - 有没有办法将加载器组件添加到 Material ui Autocomplete 组件
- php - 使用 PHP 将 CSV 文件解析为列
- multiprocessing - fortran 中系统范围的唯一文件名
- java - 我的程序返回多个结果集我可以将它们传递给执行器服务吗?
- sql-server - 来自 Oracle 的 SSIS 失败“执行升级”组件
- r - 如何更改可折叠盒子的轮廓颜色闪亮