如何在 tkinter 中创建一个自调整大小的按钮网格?

Posted

技术标签:

【中文标题】如何在 tkinter 中创建一个自调整大小的按钮网格?【英文标题】:How to create a self resizing grid of buttons in tkinter? 【发布时间】:2011-11-27 07:46:47 【问题描述】:

我正在尝试使用 Tkinter 创建一个按钮网格(以实现可点击的单元格效果)。

我的主要问题是我无法使grid 和按钮自动调整大小并适合父窗口。

例如,当我在网格上有大量按钮时,我没有缩小按钮以使网格适合窗口内部,而是得到一个超出屏幕的拉伸框架。

我正在寻找的效果是网格填充所有可用空间,然后调整其单元格的大小以适应该空间。我已阅读文档,但我仍然无法弄清楚如何使其工作。

这是我的出发点的基本代码:

def __init__(self):
    root = Tk()
    frame = Frame(root)
    frame.grid()

    #some widgets get added in the first 6 rows of the frame's grid          

    #initialize grid
    grid = Frame(frame)  
    grid.grid(sticky=N+S+E+W, column=0, row=7, columnspan=2)

    #example values
    for x in range(60):
        for y in range(30):
            btn = Button(grid)
            btn.grid(column=x, row=y)

    root.mainloop()

【问题讨论】:

【参考方案1】:

您需要将行和列配置为具有非零权重,以便它们占用额外空间:

grid.columnconfigure(tuple(range(60)), weight=1)
grid.rowconfigure(tuple(range(30)), weight=1)

您还需要配置按钮,以便它们展开以填充单元格

btn.grid(column=x, row=y, sticky="news")

这必须一直进行,所以这里有一个完整的例子:

from tkinter import *

root = Tk()
frame = Frame(root)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame.grid(row=0, column=0, sticky="news")
grid = Frame(frame)
grid.grid(sticky="news", column=0, row=7, columnspan=2)
frame.rowconfigure(7, weight=1)
frame.columnconfigure(0, weight=1)

#example values
for x in range(10):
    for y in range(5):
        btn = Button(frame)
        btn.grid(column=x, row=y, sticky="news")

frame.columnconfigure(tuple(range(10)), weight=1)
frame.rowconfigure(tuple(range(5)), weight=1)

root.mainloop()

【讨论】:

谢谢!那效果很好。我不确定为什么我没有找到 Grid 类。我正在阅读几何管理器文档,但只发现了 .grid 方法。 您的示例在我的系统上调整大小时没有展开按钮。我正在使用 32 位的 Xubuntu 14.04。我在 Python 2.x 和 3.x 上都试过了。 非常有用的例子。 @Kiril - 您还可以从对象引用中调用 columnconfigure,例如root.rowconfigure(0, weight=1) @Vaughn Cato,感谢您的出色回答!您的完整示例包含一些无关代码,因此我在刚刚发布的答案中发布了一个清理示例,并包含屏幕截图。 python27 的语法是,sticky='nsew' (not sticky=N+S+E+W)【参考方案2】:

当您使用滚动条时(至少在 Mac 中),网格权重方法可能不起作用,因此在使用它时将小部件和滚动条打包在一个框架内,然后将框架网格化。

【讨论】:

【参考方案3】:

@Vaughn Cato gave an excellent answer here。然而,他不小心在他的示例中包含了一堆无关的代码。这是一个干净且更有条理的完整示例,完全按照他的示例所做的。

from tkinter import *

#Create & Configure root 
root = Tk()
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)

#Create & Configure frame 
frame=Frame(root)
frame.grid(row=0, column=0, sticky=N+S+E+W)

#Create a 5x10 (rows x columns) grid of buttons inside the frame
for row_index in range(5):
    Grid.rowconfigure(frame, row_index, weight=1)
    for col_index in range(10):
        Grid.columnconfigure(frame, col_index, weight=1)
        btn = Button(frame) #create a button inside frame 
        btn.grid(row=row_index, column=col_index, sticky=N+S+E+W)  

root.mainloop()

截图:

第一次打开时(小):

最大化窗口后:

【讨论】:

我复制并粘贴了这个确切的示例,它在 OS X 10.13.4 和 python 3.6.4 上水平调整了“我们”而不是垂直调整大小,“ns”。我不知道为什么,但你的代码在我的 Windows 机器上运行得很好。我发现如果我使用 ttk 模块的 Button 调整大小就像你演示的那样工作。所以 OS X 用户请注意,使用 tkinter.ttk.Button 而不是 tkinter.Button 否则这将不起作用。 如何使用多个类将其实现到程序中? 这适用于复制同一个按钮 XxY 次。当你想在同一个网格中有 XxY 个不同的按钮时会发生什么?我尝试在所有按钮上将 row/col 设置为 row_index/col_index,但只有一个按钮显示 XxY 次。变量没有递增。【参考方案4】:

要让按钮在窗口最大化时展开,尝试修改button.grid条目如下:

btn.grid(column=x, row=y, sticky=N+S+E+W)

【讨论】:

以上是关于如何在 tkinter 中创建一个自调整大小的按钮网格?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python Tkinter 中创建一个按钮以将整数变量增加 1 并显示该变量?

在 PySimpleGui 中创建自定义按钮

在 tkinter 类中创建一个切换按钮

如何在使用它的 ViewController 上调整自定义(在单独的文件中创建)UIView 高度?

在 Tkinter 中创建向导

如何根据需要调整背景图像的大小