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

发布于 2024-12-07 12:32:22 字数 682 浏览 1 评论 0原文

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

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

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

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

这是基本代码,这是我的起点:

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()

I am trying to create a grid of buttons(in order to achieve the clickable cell effect) with Tkinter.

My main problem is that I cannot make the grid and the buttons autoresize and fit the parent window.

For example, when I have a high number of buttons on the grid, instead of shrinking the buttons so that the grid fits inside the window, I get a stretched frame that goes off screen.

The effect that I am looking for is the grid filling all available space, then resizing its cells to fit within that space. I have read at the documentation, but I still cannot figure out how to make it work.

This is the basic code which is my starting point:

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

快乐很简单 2024-12-14 12:32:23

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

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

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

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()

You need to configure the rows and columns to have a non-zero weight so that they will take up the extra space:

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

You also need to configure your buttons so that they will expand to fill the cell:

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

This has to be done all the way up, so here is a full example:

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()
自由范儿 2024-12-14 12:32:23

@Vaughn Cato 在这里给出了一个很好的答案。然而,他不小心在他的示例中包含了一堆无关的代码。这是一个经过清理且更有组织的完整示例,其功能与他的示例完全相同。

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()

屏幕截图:

首次打开时(小):

在此处输入图像描述

最大化窗口后:

在此处输入图像描述

TODO

  1. [ ] 2023 年 8 月 3 日:更新&使我的例子现代化。我应该看看的主要答案发生了一些变化。
  2. [ ] 2023 年 8 月 3 日:删除 from tkinter import *,并使用 import tkinter 代替,如下
    全部导入是不好的做法。最好明确地看到在哪里
    每个对象都来自显式使用模块的名称空间。

@Vaughn Cato gave an excellent answer here. However, he has accidentally included a bunch of extraneous code in his example. Here is a cleaned up and more organized full example doing exactly what his example does.

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()

Screenshots:

When it first opens (small):

enter image description here

After you maximize the window:

enter image description here

TODO

  1. [ ] 3 Aug. 2023: Update & modernize my example. Some changes occurred to the main answer that I should look at.
  2. [ ] 3 Aug. 2023: Remove from tkinter import *, and use import tkinter instead, as
    it's bad practice to import all. It's better to see explicitly where
    each object comes from by using a module's namespace explicitly.
深海蓝天 2024-12-14 12:32:23

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

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

To make the buttons expand when the window is maximized, try to modify the button.grid entry as follows:

btn.grid(column=x, row=y, sticky=N+S+E+W)
下雨或天晴 2024-12-14 12:32:23

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

The grid weight method might not work when you use scrollbar (at least in Mac) , so while using it pack the widget and scrollbar inside a frame and then grid the frame instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文