Как создать самоизменяющуюся сетку кнопок в tkinter? - PullRequest
38 голосов
/ 29 сентября 2011

Я пытаюсь создать сетку кнопок (для достижения эффекта кликабельной ячейки) с помощью 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()

Ответы [ 3 ]

49 голосов
/ 29 сентября 2011

Вам необходимо настроить строки и столбцы так, чтобы они имели ненулевой вес , чтобы они занимали дополнительное пространство:

for x in range(60):
    Grid.columnconfigure(grid, x, weight=1)

for y in range(30):
    Grid.rowconfigure(grid, y, weight=1)

Вам также необходимо настроить кнопкитак что они будут расширяться, чтобы заполнить ячейку :

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

Это должно быть сделано до конца, так что вот полный пример:

from tkinter import *

root = Tk()
frame=Frame(root)
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
frame.grid(row=0, column=0, sticky=N+S+E+W)
grid=Frame(frame)
grid.grid(sticky=N+S+E+W, column=0, row=7, columnspan=2)
Grid.rowconfigure(frame, 7, weight=1)
Grid.columnconfigure(frame, 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=N+S+E+W)

for x in range(10):
  Grid.columnconfigure(frame, x, weight=1)

for y in range(5):
  Grid.rowconfigure(frame, y, weight=1)

root.mainloop()
20 голосов
/ 07 августа 2016

@ Вон Катон дал отличный ответ здесь . Тем не менее, он случайно включил кучу постороннего кода в своем примере. Вот приведенный в пример очищенный и более организованный пример, делающий именно то, что делает его пример

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

Скриншоты:

Когда он впервые открывается (маленький):

enter image description here

После того, как вы развернули окно:

enter image description here

3 голосов
/ 30 апреля 2015

Чтобы кнопки расширялись, когда окно развернуто, попробуйте изменить запись button.grid следующим образом:

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