如何在tkinter中创建自适应大小的按钮网格?
我正在尝试用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()
截图:
第一次打开时(小窗口):
当你把窗口最大化后:
待办事项
- [ ] 2023年8月3日:更新并现代化我的示例。主答案有一些变化,我应该看看。
- [ ] 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()