【问题标题】:Tkinter rescaling frame size when switching from pack() to grid() method从 pack() 切换到 grid() 方法时,Tkinter 重新调整帧大小
【发布时间】:2019-12-02 21:58:50
【问题描述】:

我需要我的界面看起来像这样:

每种颜色都是一个单独的框架,在每个框架内我定义了一些标签。

from tkinter import *

root = Tk()
root.title("Library program")
root.geometry('{}x{}'.format(900, 450))
root.resizable(width=False, height=False)

#define main containers
topFrame = Frame(root, width=450, height=50, pady=3)
bottomFrame = Frame(root, width=450, height=50)

#main container layouts
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

topFrame.grid(row=0, sticky="nsew")
bottomFrame.grid(row=1, sticky="nsew")

#define additional containers
bottomFrame.grid_rowconfigure(0, weight=1)
bottomFrame.grid_columnconfigure(1, weight=1)

bottomLeft = Frame(bottomFrame, width=225, bg="red")
bottomMidLeft = Frame(bottomFrame, width=225, bg="blue")
bottomMidRight = Frame(bottomFrame, width=225, bg="yellow")
bottomRight = Frame(bottomFrame, width=225, bg="green")

bottomLeft.pack_propagate(0)
bottomMidLeft.pack_propagate(0)
bottomMidRight.pack_propagate(0)
bottomRight.pack_propagate(0)

bottomLeft.grid(row=0, column=0, sticky = "nsew")
bottomMidLeft.grid(row=0, column=1, sticky = "nsew")
bottomMidRight.grid(row=0, column=2, sticky = "nsew")
bottomRight.grid(row=0, column=3, sticky = "nsew")

#top container widgets
titleLabel = Label(topFrame, text="Jakub's Library Program", font="Calibri 20")
titleLabel.pack()

#bottom container widgets
leftLabel = Label(bottomLeft, text="Book Search", font="Calibri")
midLeftLabel = Label(bottomMidLeft, text="Book Checkout", font="Calibri")
midRightLabel = Label(bottomMidRight, text="Return Books", font="Calibri")
rightLabel = Label(bottomRight, text="Popular Books", font="Calibri")

leftLabel.grid(row=0, column=0)
midLeftLabel.pack()
midRightLabel.pack()
rightLabel.pack()

bookTitleLabel = Label(bottomLeft, text="Book title", font="Calibri 12")
bookTitleEntry = Entry(bottomLeft)

bookTitleLabel.grid(row=1, column=0)
bookTitleEntry.grid(row=1, column=1)

root.mainloop()

但由于我需要像红框一样放置标签和条目,所以我使用 grid() 而不是 pack() 将标签放置在每个框架中。

leftLabel.grid(row=0, column=0)
midLeftLabel.grid(row=0, column=0)
midRightLabel.grid(row=0, column=0)
rightLabel.grid(row=0, column=0)

现在我的界面如下所示:

当使用 grid() 显示左下角的标签时没有问题,但是一旦使用 grid() 显示剩余的标签,由于某种原因它会抛出框架的大小。

【问题讨论】:

  • 您对此进行过研究吗?这个网站上有很多与网格相关的问题。其中大多数与未正确配置行和/或列的权重有关。
  • @BryanOakley 我有,但我什至不明白程序为了能够根据标签的网格更改框架的大小而发生了什么变化。特别是因为我使用了 grid_propagate(0)。
  • 您不会在您发布的代码中的任何地方调用grid_propagate(0)
  • @BryanOakley 我的意思是 pack_propagate(0) 我很抱歉。
  • 这不是一个好主意(使用pack_propagate)。你的最终目标是什么?您的目标是拥有四个相同大小的列吗?在第一个屏幕截图中,它们并不是 100% 相等的,所以你要做什么并不完全清楚。

标签: python-3.x tkinter


【解决方案1】:

如果您的目标是创建四个大小相等的列,grid 让这一切变得非常简单。您需要确保每列具有相同的非零权重,并且您需要为 uniform 选项赋予每列相同的值。

您还应该删除对pack_propagate 的调用。关闭几何传播很少是正确的做法。如果您想被要求进行大量数学运算以确保一切都合适,这是一个不错的解决方案,但是让 tkinter 完成所有工作以使一切都合适会更容易。

删除此块:

bottomLeft.pack_propagate(0)
bottomMidLeft.pack_propagate(0)
bottomMidRight.pack_propagate(0)
bottomRight.pack_propagate(0)

添加这行代码:

bottomFrame.grid_columnconfigure((0,1,2,3), uniform="equal", weight=1)

注意:这将导致您的条目小部件被剪裁。那是因为您 a) 强制窗口为特定大小,b) 将该大小分成四个相等的列,c) 使用条目小部件的默认大小,考虑到您的其他设计选择,该大小太大而无法适应。

更好的方法是不要将窗口强制为特定大小。相反,让内容决定窗口的大小。您可以专注于内部小部件的最佳尺寸,并让 tkinter 完成决定窗口需要多大的所有工作。

在任何一种情况下(无论是否强制窗口大小),都无需为框架指定宽度,因为grid 将调整它们的大小以适应。

我还建议删除root.resizable(width=False, height=False)。删除用户调整窗口大小的能力是一件非常用户友好的事情。

【讨论】:

    猜你喜欢
    • 2016-06-29
    • 2012-11-07
    • 2011-10-13
    • 1970-01-01
    • 2012-08-21
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多