首页 > 解决方案 > 关于在网格内排列 Tkinter 中的帧的问题,试图在一个帧内使用 .grid() 和 .pack() 获得相同的结果

问题描述

python 新手,从这个网站获得了很多很棒的信息。

我正在使用 .grid() 创建一个图表,然后再次使用 .pack() 中的框架作为练习,看看我是否可以获得相同的结果。

函数 showchart_grid() 工作并产生几乎我想要创建的东西。这是一个图表,底行是 14 个方格,顶行是这些方格的标签,有时列标签跨越 2 个方格。您可以在 columnspan= 属性中看到这一点。第 0 行的列标签之间有一些奇怪的空白,但除此之外,它都排成一行。

def showchart_grid():
    root = Tk()

    # create 14 squares on the grid

    for i in range(1, 15):

        spot = Label(root, text='square', bg='white', height=5, width=10, borderwidth=1, relief='solid', justify=CENTER)
        spot.grid(row=1, column=i)

    # create the column labels on top of the grid in row one

    label0 = Label(root, text=0, bg="DodgerBlue", fg="white", height=2, width=10, borderwidth=1, relief='solid')
    label0.grid(row=0, column=1)
    label1 = Label(root, text=1, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label1.grid(row=0, column=2, columnspan=2)
    label2 = Label(root, text=2, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label2.grid(row=0, column=4, columnspan=2)
    label4 = Label(root, text=4, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label4.grid(row=0, column=6, columnspan=2)
    label6 = Label(root, text=6, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label6.grid(row=0, column=8, columnspan=2)
    label8 = Label(root, text=8, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label8.grid(row=0, column=10, columnspan=2)
    label11 = Label(root, text=11, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label11.grid(row=0, column=12, columnspan=2)
    label15 = Label(root, text=15, bg="CadetBlue1", height=2, width=10, borderwidth=1, relief='solid')
    label15.grid(row=0, column=14)

    mainloop()

现在,当我尝试通过为列标签创建一个框架和为正方形创建一个框架来做同样的事情时,即使大小相同,位置也不再匹配。就好像列标签没有填满整个框架。我已经搞砸了 fill= 和 expand= 但无法弄清楚到底是怎么回事。注意:这个版本解决了列标签之间奇怪的空白问题。

def showchart_framespack_test():
    root = Tk()

    # define my frames

    pointsframe = Frame(root, width=140)
    pointsframe.pack(side=TOP)

    playerframe = Frame(root, width=140)
    playerframe.pack(side=TOP)

    # create bottom row of squares with pack

    for i in range(1, 15):

        spot = Label(playerframe, text='empty', bg='white', height=5, width=10, borderwidth=1, relief='solid', justify=CENTER)
        spot.pack(side=LEFT)

    # create top row of labels with pack

    label0 = Label(pointsframe, text=0, bg="DodgerBlue", fg="white", height=2, width=10, borderwidth=1, relief='solid')
    label0.pack(side=LEFT)
    label1 = Label(pointsframe, text=1, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label1.pack(side=LEFT)
    label2 = Label(pointsframe, text=2, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label2.pack(side=LEFT)
    label4 = Label(pointsframe, text=4, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label4.pack(side=LEFT)
    label6 = Label(pointsframe, text=6, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label6.pack(side=LEFT)
    label8 = Label(pointsframe, text=8, bg='CadetBlue1', height=2, width=20, borderwidth=1, relief='solid')
    label8.pack(side=LEFT)
    label11 = Label(pointsframe, text=11, bg='DodgerBlue', height=2, width=20, borderwidth=1, relief='solid')
    label11.pack(side=LEFT)
    label15 = Label(pointsframe, text=15, bg="CadetBlue1", height=2, width=10, borderwidth=1, relief='solid')
    label15.pack(side=LEFT)



mainloop()

如何改进此处的编程以获得我想要的底部 14 个正方形的结果,顶部的标签与底部行的 14 个正方形的边界完美对齐?

PS这些是函数,因为它们会接受输入并调整图表,但现在我只是把它一直保留为“空”。

标签: pythonpython-3.xmacostkinter

解决方案


从根本上说,网格是一种二维布局。如果将两个项目分配给同一列,则它们垂直排列。

另一方面,pack 是一种一维布局,可以相对于其他元素定位元素。

在您的第二个示例中,您正在创建两个彼此独立的水平元素列表。两者都有相同数量的项目,但元素不会排列,因为“列”是为两个框架单独计算的。

如果您可以在没有跨越多列的单元格的情况下生活,您可以通过创建 15 个框架来排列列,每个框架包含一个标签和一个正方形,并使用 pack 将它们彼此相邻放置。

除此之外,您的用例确实是网格布局的设计目的。我对所有事情都使用网格,因为在我看来它更灵活,更容易推理。

这回答了你的问题了吗?

编辑:

如果您使用该sticky="WE"选项而不是手动指定每个标签的宽度,则可以消除间隙。这将使它跨越左右。修改后的代码:

from tkinter import *

def showchart_grid():
    root = Tk()

    # create 14 squares on the grid

    for i in range(1, 15):

        spot = Label(root, text='square', bg='white', height=5, width=10, borderwidth=1, relief='solid', justify=CENTER)
        spot.grid(row=1, column=i)

    # create the column labels on top of the grid in row one

    label0 = Label(root, text=0, bg="DodgerBlue", fg="white", height=2, borderwidth=1, relief='solid')
    label0.grid(row=0, column=1, sticky="WE")
    label1 = Label(root, text=1, bg='CadetBlue1', height=2, borderwidth=1, relief='solid')
    label1.grid(row=0, column=2, sticky="WE", columnspan=2)
    label2 = Label(root, text=2, bg='DodgerBlue', height=2, borderwidth=1, relief='solid')
    label2.grid(row=0, column=4, sticky="WE", columnspan=2)
    label4 = Label(root, text=4, bg='CadetBlue1', height=2, borderwidth=1, relief='solid')
    label4.grid(row=0, column=6, sticky="WE", columnspan=2)
    label6 = Label(root, text=6, bg='DodgerBlue', height=2, borderwidth=1, relief='solid')
    label6.grid(row=0, column=8, sticky="WE", columnspan=2)
    label8 = Label(root, text=8, bg='CadetBlue1', height=2, borderwidth=1, relief='solid')
    label8.grid(row=0, column=10, sticky="WE", columnspan=2)
    label11 = Label(root, text=11, bg='DodgerBlue', height=2, borderwidth=1, relief='solid')
    label11.grid(row=0, column=12, sticky="WE", columnspan=2)
    label15 = Label(root, text=15, bg="CadetBlue1", height=2, borderwidth=1, relief='solid')
    label15.grid(row=0, column=14, sticky="WE")

    mainloop()


if __name__ == '__main__':
    showchart_grid()

推荐阅读