我正在尝试创建两个Label小部件,它们位于我的测试UI的左上角和右上角.问题是小部件粘在一起,我希望它们之间有空间.
在我的研究中,我遇到了使用粘性,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)
Bry*_*ley 67
您需要使用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.它们既强大又擅长于不同的事物.唯一要记住的 - 这是至关重要的 - 是你不能在同一个父母中使用它们.使用您的代码作为示例,您不能pack用于top_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由于您不必担心行和列权重,因此更容易使用.
| 归档时间: | 
 | 
| 查看次数: | 67730 次 | 
| 最近记录: |