我将如何继续将小部件放置在处于缩放状态且在使用时无法调整大小的框架上.grid()?
我希望能够将按钮放在屏幕的最右侧,同时在屏幕的左侧放置一个树状视图,例如在中间有一个“空白”的实例。我不确定是否可以亲自完成,根据我对 tkinter 的经验,我只使用了不是“缩放”或“全屏”的较小窗口,这使得.grid()放置非常容易使用而没有这个问题。我在网上寻找解决方案,但还没有找到。
我希望能够在下面提供的布局中布局我的 tkinter 窗口。

关于此类问题的令人沮丧的事情是 a) 至少有六种方法可以完成您想要的任务,并且 b) 最好的方法取决于您尚未定义的变量。例如,您如何决定每个部分的比例——您是否对它们进行了硬编码,您是否希望 tkinter 根据里面的内容来计算它们?如果用户调整窗口大小,您想要什么行为?等等。
让我们从导入语句和根窗口开始。我讨厌全屏窗口,所以我要使用较小的固定尺寸。无论大小如何,布局都可以使用,您可以将其调整为任何您想要的大小。
import tkinter as tk
root = tk.Tk()
root.geometry("900x600")
Run Code Online (Sandbox Code Playgroud)
接下来,让我们为每个部分创建一个框架。每个帧都将使用图像中的颜色,使其更易于可视化。我可以使用任何小部件,但框架是最常见的小部件,可用作其他小部件的容器(例如,带有滚动条的树视图或文本小部件、可能带有按钮的图形等)
treeview_frame = tk.Frame(root, background="#FFF0C1", bd=1, relief="sunken")
graph_frame = tk.Frame(root, background="#D2E2FB", bd=1, relief="sunken")
text_frame = tk.Frame(root, background="#CCE4CA", bd=1, relief="sunken")
button_frame = tk.Frame(root, background="#F5C2C1", bd=1, relief="sunken")
Run Code Online (Sandbox Code Playgroud)
有了这个,我们可以布置小部件。我们可以pack很容易地使用它,但grid在您学习时会更容易理解。
当我查看您的图片时,我很清楚您有两行三列。看起来第一列(第 0 列)比其他列宽一点。同样,第一行(第 0 行)看起来比另一行高一点。我们稍后会用到这些信息。
首先,让我们将所有内容放在各自的行和列中。这应该很明显,所以我让代码来解释。
treeview_frame.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
graph_frame.grid(row=1, column=0, sticky="nsew", padx=2, pady=2)
text_frame.grid(row=0, column=1, rowspan=2, sticky="nsew", padx=2, pady=2)
button_frame.grid(row=0, column=2, rowspan=2, sticky="nsew", padx=2, pady=2)
Run Code Online (Sandbox Code Playgroud)
接下来是几乎所有初学者都忘记的非常重要的步骤:您需要为每一行和每一列赋予权重。权重决定了如何grid分配额外空间。既然你说你想要一个缩放的窗口,那么在添加你的实际小部件后你可能会有一堆额外的空间。
这是相对宽度和高度的用武之地。该weight属性是一个值,用于指定如何分配额外空间。例如,如果您有一个权重为 1(一)的列,另一个权重为 2,那么权重为 2 的列将获得另一个权重的两倍的额外空间。例如,如果 tkinter 计算出它需要填充 100 个额外的像素,它将为一个提供 66 或 67 个像素,为另一个提供 33 或 34 个像素。
需要记住的是,行和列的权重为 0(零)。这意味着他们没有得到任何额外的空间。
根据经验,大部分权重应该分配给屏幕上的“主要”小部件。对于将是文本小部件的文本编辑器,对于绘图应用程序,它可能是画布。对于报告应用程序,它可能是树视图。由于您拥有所有这些,我不知道您希望如何分配空间。
我会猜测,并说树视图所在的第 0 行应该占据高度的一半多一点。我将给它一个权重 3,另一个权重为 2。如果你希望树视图和图形的大小相同,你会给它们每个的权重为 1。如果图形是固定大小,但是树视图应该尽可能大,给图的权重为 0(零),树的权重为 1。
root.grid_rowconfigure(0, weight=3)
root.grid_rowconfigure(1, weight=2)
Run Code Online (Sandbox Code Playgroud)
现在我们需要对列进行相同的练习。看起来第一列,即零列,只比其他列占用更多的空间。所以,我给它的权重为 3,其他的权重为 2。与行一样,您可以将所有权重放在一列中,平均分配,或者随心所欲。
root.grid_columnconfigure(0, weight=3)
root.grid_columnconfigure(1, weight=2)
root.grid_columnconfigure(2, weight=2)
Run Code Online (Sandbox Code Playgroud)
就是这样,对于基本布局。
如果您root.mainloop()在所有代码的末尾调用,您将拥有一个与您提供的图片几乎完全相同的窗口。请注意,当您调整窗口大小时,它都会很好地缩放。
现在您可以开始向每个框架添加小部件,而不必太担心它们如何影响窗口的其余部分。不仅如此,您还可以将其pack用于某些grid或place其他用途。例如,如果您希望树视图具有滚动条,您可以像这样创建它:
tree = ttk.Treeview(treeview_frame)
sb = ttk.Scrollbar(treeview_frame)
sb.pack(side="right", fill="y")
tree.pack(side="left", fill="both", expand=True)
Run Code Online (Sandbox Code Playgroud)
唯一可能让您感到惊讶的是,如果您放入一个非常大的小部件,它可能会弄乱比例。最简单的解决方案通常是将宽度和高度设置为较小的值,并让它适应。如果你把它变大,它会想要变大,把其他小部件推开。