您需要使用
grid_columnconfigure来赋予中间的列一些权重。与其他列相比,它们的权重更大,它们会扩展和收缩以填充您拥有的任何额外空间。但是,在您的情况下,实际上不需要使用网格。GUI中的所有内容都沿着特定的边对齐,这
pack更加自然。
我将展示如何使用pack和grid,从pack开始,因为它是最简单的。即使您坚持使用
grid,也请通读下一节以了解如何将一个大的布局问题分解为许多较小的布局问题。
分而治之
在Tkinter中进行布局的最佳方法是“分而治之”。从最外面的小部件开始,并按照您想要的方式获得它们。然后,一次解决所有这些问题。
在您的情况下,您有一个最外面的小部件-
主容器。由于它是窗口中唯一的窗口小部件,因此pack是使它填充整个容器的最简单方法。您也可以使用网格,但是需要一些额外的工作:
self.main_container = frame(parent. background="bisque")self.main_container.pack(side="top", fill="both", expand=True)
它有助于暂时为框架提供独特的颜色,以便您在开发时可以形象地看到它们。仅将上述代码添加到中
__init__,运行您的应用程序,然后调整窗口大小以查看主框架正确地增大和缩小。
接下来,您有两个框架-
top_frame和bottom_frame。根据它们的名称和您尝试使用网格的方式来判断,我认为它们应该在x方向上填充GUI。另外,我猜最上面的框架是某种工具栏,最下面的框架是GUI的真正“主要”部分。因此,让我们让底部小部件占用所有多余的空间。
由于它们相互堆叠,
pack因此又是自然的选择。添加以下代码-仅添加以下代码-确保这些区域占据了您期望的窗口部分,并确保它们具有适当的调整大小行为。
self.top_frame = frame(self.main_container, background="green") self.bottom_frame = frame(self.main_container, background="yellow") self.top_frame.pack(side="top", fill="x", expand=False) self.bottom_frame.pack(side="bottom", fill="both", expand=True)
接下来是标签的框架。同样,这些容器沿容器边缘占据空间,因此
pack最有意义。再次,仅添加以下代码,运行程序,并确保一切仍在正确调整大小并填充窗口的正确部分:
self.top_left = frame(self.top_frame, background="pink") self.top_right = frame(self.top_frame, background="blue") self.top_left.pack(side="left", fill="x", expand=True) self.top_right.pack(side="right", fill="x", expand=True)
接下来,您将具有“角”标签。同样,由于容器仅是一行小部件,因此
pack变得很容易。由于您希望标签贴在角落,因此我们将为
sticky每个标签设置稍有不同的属性:
self.top_left_label = Label(self.top_left, text="Top Left") self.top_right_label = Label(self.top_right, text="Top Right") self.top_left_label.pack(side="left") self.top_right_label.pack(side="right")
最后,您有了文本小部件。它填满了整个底部框架,因此
pack我们的朋友再次成为:
self.text_box = Text(self.bottom_frame, height=5, width=40, background="gray") self.text_box.pack(side="top", fill="both", expand=True)
打包还是网格?
您将网格用于原始代码,并询问如何修复它。为什么我使用pack作为示例?
使用时
pack,所有配置选项都可以包装在一个调用中。除了
grid将小部件放入其容器中之外,还必须注意使各个列和行具有“权重”,以便正确调整它们的大小。当您简单地将小部件堆叠在一起或将它们排成一行时,
pack使用起来会容易得多。
在我的图形用户界面,我几乎总是使用的组合
grid和
pack。它们既强大,又在不同方面表现出色。要记住的唯一一件事- 这很关键
-您不能在同一个父母中使用它们。以您的代码为例,您不能使用
packtop_left框架和
gridtop_right框架,因为它们共享相同的父对象。但是,您
可以 将它们混合在同一应用程序中。
再次使用网格
好的,所以也许您真的想使用
grid:也许这是学校的作业,或者您只想一次专注于一位几何经理。这很酷。这就是我的做法。同样,您必须分而治之:
从主机开始。用以下几行替换我们将主容器打包的一个语句。请注意,我们必须在 父级 (而不是我们创建的框架)上配置行和列。
self.main_container.grid(row=0, column=0, sticky="nsew") self.myParent.grid_rowconfigure(0, weight=1) self.myParent.grid_columnconfigure(0, weight=1)
好的,现在是顶部和底部框架。删除
pack,然后添加以下行。您仍然只有一列,但是这次有几行。注意哪一行的权重为1:
self.top_frame.grid(row=0, column=0, sticky="ew") self.bottom_frame.grid(row=1, column=0,sticky="nsew") self.main_container.grid_rowconfigure(1, weight=1) self.main_container.grid_columnconfigure(0, weight=1)
角架-最后是一个多列的容器!让我们在中间创建第三列以解决所有的松弛问题。用
pack以下内容代替语句,并密切注意“权重”的含义:
self.top_left.grid(row=0, column=0, sticky="w") self.top_right.grid(row=0, column=2, sticky="e") self.top_frame.grid_columnconfigure(1, weight=1)
接下来,在其框架中的标签。由于我们不需要扩展它们,因此我们可以将默认权重保持为零。您可能会觉得两个标签都位于零列中很奇怪。请记住,它们在不同的父级中,并且它们是父级中唯一的窗口小部件,因此每个窗口中只有一列:
self.top_left_label.grid(row=0, column=0, sticky="w") self.top_right_label.grid(row=0, column=0, sticky="e")
最后,我们有文本小部件,它是底部框架中唯一的小部件。将最终
pack声明替换为以下内容:
self.text_box.grid(row=0, column=0, sticky="nsew") self.bottom_frame.grid_rowconfigure(0, weight=1) self.bottom_frame.grid_columnconfigure(0, weight=1)
结论
布置小部件很容易,但是您必须对此进行系统的设计。考虑一下您在做什么,将小部件组织成组,然后一次将其解决。当您执行此操作时,应该清楚地知道应该使用哪个几何管理器。
如您所见,它
grid需要多几行代码,但是当您确实有网格时,这是正确的选择。在您的情况下,您已经将GUI细分为多个部分,因此,即使最终结果是一个网格,每个部分还是被包装在另一个的顶部或下方,或者被包装在左侧或右侧。在这些情况下,
pack由于您不必担心行和列的权重,因此使用起来会更容易一些。



