python - 如何在 tkinter 中巧妙地创建带有可调整大小的小部件的可调整大小的窗口?

标签 python tkinter window-resize

所以我使用 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")

正如您在下面看到的,复选框没有对齐,当我展开窗口时,它会进一步向外:

Part of my window

Resized Window

我花了很长时间才让它们保持一致,但实际上不应该。我喜欢使用 .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()

最佳答案

解决方案是使用gridpack——它们是专门为创建响应式用户界面而设计的。如果您非常关心响应能力,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")

窗口现在完全响应。另外,添加更多选项或重新排列选项的顺序也很简单。这是原始尺寸:

screenshot of original window

这是窗口展开的情况:

screenshot of resized window

关于python - 如何在 tkinter 中巧妙地创建带有可调整大小的小部件的可调整大小的窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59410902/

相关文章:

python - 使用 Mongoengine 和 Pyramid 将数据保存到嵌入式文档的正确方法是什么?

使用 csv 或 pandas 模块的 python csv 到字典

python - 在 tkinter python 中围绕光标绘制一个定义大小的圆圈

popup - 增加Chrome扩展程序中的最大弹出窗口宽度?

python - GAE 柔性环境 postgres 连接字符串?

python - 如何解决 -discord.http : We are being rate limited. 回复 429

python - tkinter ttk.Combobox 下拉/展开并聚焦于文本

Python tkinter 模块文本转换

jquery - 使用 jQuery 在窗口调整大小时动态更改 CSS

javascript - d3 v4 中差分力 'center' 之间的转换