如何在tkinter中创建自适应大小的按钮网格?

63 投票
4 回答
127826 浏览
提问于 2025-04-17 03:19

我正在尝试用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()

4 个回答

4

为了让按钮在窗口最大化时能够扩展,可以尝试这样修改按钮的.grid设置:

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

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

截图:

第一次打开时(小窗口):

这里输入图片描述

当你把窗口最大化后:

这里输入图片描述

待办事项

  1. [ ] 2023年8月3日:更新并现代化我的示例。主答案有一些变化,我应该看看。
  2. [ ] 2023年8月3日:去掉 from tkinter import *,改用 import tkinter,因为直接导入所有内容是不好的做法。明确每个对象来自哪里,使用模块的命名空间会更好。
88

你需要设置行和列的非零权重,这样它们才能占据额外的空间:

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

撰写回答