当前位置: 首页 > 面试题库 >

Tkinter Grid:如何定位小部件,以防止它们粘在一起

上官斌
2023-03-14
问题内容

我试图在我的测试UI的左上角和右上角创建两个Label窗口小部件。问题是小部件被粘在一起,我希望它们之间有空间。

在我的研究中,我遇到了使用sticky,padx和pady选项的建议。但是,无论我传递给.grid()的参数是什么,我似乎都无法在小部件之间创建空间。我知道无论两个小部件之间的列数和行数如何,如果所说的行/列为空,就好像它们不存在,并且小部件看上去粘在一起。

使用.grid()方法,如何定位小部件以免它们粘在一起?

到目前为止,这是我的代码:

#!/usr/bin/python
from Tkinter import *

class MyApp:
    def __init__(self, parent):
        self.myParent = parent
        self.main_container = Frame(parent)
        self.main_container.grid(row=0, rowspan=2, column=0, columnspan=4)

        self.top_frame = Frame(self.main_container)
        self.top_frame.grid(row=0, column=0, columnspan=4)

        self.top_left = Frame(self.top_frame)
        self.top_left.grid(row=0, column=0, columnspan=2)

        self.top_right = Frame(self.top_frame)
        self.top_right.grid(row=0, column=2, columnspan=2)

        self.bottom_frame = Frame(self.main_container)
        self.bottom_frame.grid(row=2, column=0, columnspan=4)

        self.top_left_label = Label(self.top_left, text="Top Left")
        self.top_left_label.grid(row=0, column=0, sticky='W', padx=2, pady=2)

        self.top_right_label = Label(self.top_right, text="Top Right")
        self.top_right_label.grid(row=0, column=4, sticky='E', padx=2, pady=2)

        self.text_box = Text(self.bottom_frame, height=5, width=40)
        self.text_box.grid(row=0, column=0)

root = Tk()
root.title("Test UI")
myapp = MyApp(root)
root.mainloop()

〜更新〜

我尝试了以下操作,但没有成功:

    self.top_left = Frame(self.top_frame)
    self.top_left.grid(row=0, column=0, columnspan=2)
    for c in range(2):
        self.top_left.columnconfigure(c, weight=2)

    self.top_right = Frame(self.top_frame)
    self.top_right.grid(row=0, column=2, columnspan=2)
    for c in range(2):
        self.top_right.columnconfigure(c, weight=2)

问题答案:

您需要使用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使用起来会容易得多。

在我的图形用户界面,我几乎总是使用的组合gridpack。它们既强大,又在不同方面表现出色。要记住的唯一一件事- 这很关键
-您不能在同一个父母中使用它们。以您的代码为例,您不能使用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由于您不必担心行和列的权重,因此使用起来会更容易一些。



 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : 9年前关闭。 可能重复: 什么是SQL注入? 我看到很多php代码在stackoverflow上四处飘荡,字符串的转义太少了。 谁能 说明什么是SQL注入; 说明它可以对您的服务器,数据和代码执行的操作; 举例说明如何执行SQL注入 给php示例代码如何防止SQL注入 问题答案: 我也无法抗拒。 SQL注入是“一种代码注入技术,可利用应用程序数据库层中发

  • 问题内容: 通常,我从现有代码库中复制和粘贴代码。Eclipse经常会带来我不需要的错误导入语句 例如,我将代码复制并粘贴到我的项目包中,并命名为一个名为 并在java文件中添加 这会导致错误。当然不能,为什么什至在我什至没有选择要复制的地方尝试导入该零件 我可以想象在这里方便的地方,但是这对我来说从来都不方便,而且维修起来如此耗时。 如何在Eclipse中使用Eclipse关闭此功能。 问题答案

  • 我已经将问题从居中改为自定义的位置。 因为我注意到实际上是居中的,根据文档,它只是添加了页签。 但是如果您希望在避开安全区域时设置一个制表符,或者选项卡中的元素不是(自动)居中对齐,我现在找不到方法。 我还尝试将选项卡包装在小部件中,并获得属性集,但似乎所有的高度都避开了安全区域(通过添加一个常量)。我尝试用小部件包装整个,但是安全区域变成了黑色,我们实际上希望tab bat变得更高,然后在这个更

  • 问题内容: 我有一个中心对齐的DIV网站。现在,有些页面需要滚动,有些不需要。当我从一种类型移动到另一种类型时,滚动条的外观会将页面向侧面移动几个像素。如果没有在每个页面上明确显示滚动条,有什么办法可以避免这种情况? 问题答案: overflow-y:scroll是正确的,但是您应该将其与html标记一起使用,而不是body,否则在IE 7中 会出现一个双滚动条,因此正确的CSS是:

  • 使用Java,我用GridBagLayout创建一个表单。GUI在一个J面板中,它在一个添加到JFrame的scrollPane中。 我希望带有GUI的JPanel的大小是固定的,以防止表单被拉伸,但是,我希望JScrollPanel可以根据用户的喜好调整大小。(类似于MS Paint,画布是我的JPanel)。我想要防止表单被拉伸的原因是因为我希望它能够打印,并且从我现在的方式来看,打印的表单几

  • 问题内容: 我应该怎么做才能防止Spring MVC中的XSS?现在,我只是将输出用户文本的所有位置都放入标签或函数中,但这似乎容易出错,因为我可能会错过一个位置。 有没有简单的系统方法可以防止这种情况?也许像过滤器之类的?我通过在控制器方法上指定参数来收集输入。 问题答案: 在Spring中,你可以从标记生成的JSP页面中转义html 。这为XSS攻击提供了很多途径,并且可以通过以下三种方式自动