首页 > 解决方案 > 如何在 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()

标签: pythontkinterwindow-resize

解决方案


解决方案是使用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")

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

原始窗口截图

这是窗户被拉开的情况:

调整大小的窗口的屏幕截图


推荐阅读