Python tkinter размещение элементов
Метод grid() позволяет поместить виджет в определенную ячейку условной сетки или грида.
Метод grid применяет следующие параметры:
- column : номер столбца, отсчет начинается с нуля
- row : номер строки, отсчет начинается с нуля
- columnspan : сколько столбцов должен занимать элемент
- rowspan : сколько строк должен занимать элемент
- ipadx и ipady : отступы по горизонтали и вертикали соответственно от границ элемента до его содержимого
- padx и pady : отступы по горизонтали и вертикали соответственно от границ ячейки грида до границ элемента
- sticky : выравнивание элемента в ячейке, если ячейка больше элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, которые указывают соответствующее направление выравнивания
Установка ячейки виджета
Например, определим грид из 9 кнопок:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for r in range(3): for c in range(3): btn = ttk.Button(text=f"(,)") btn.grid(row=r, column=c) root.mainloop()
Здесь в цикле создается девять кнопок, каждая из которых помещается в свою ячейку. В итоге у нас получится следующий грид
По умолчанию для каждой ячейки выделяется столько места, сколько необходимо для виджета в ней. Соответственно мы получаем небольшую таблицу и много пустого места вне грида, что, возможно, смотрится не лучшим образом. И ситуация усугубляется, если мы попробуем растянуть окно — появится еще больше пустого пространства. Чтоюбы решить эту проблему, надо сконфигурировать грид у контейнера.
Конфигурация грида
Для конфигурации грида в контейнере применяются два метода:
container.columnconfigure(index, weight) container.rowconfigure(index, weight)
Метод columnconfigure() настраивает столбец. В качестве параметра index метод получает индекс столбца, а через параметр weight устанавливает его вес. Столбцы распределяются по всей ширине контейнера в соответствии со своим весом.
Метод rowconfigure() настраивает строку аналогичным образом. В качестве параметра index метод получает индекс строки, а через параметр weight устанавливает ее вес. Строки распределяются по всей длине контейнера в соответствии со своим весом.
Например, изменим код выше, добавив конфигурацию строк и столбцов:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for c in range(3): root.columnconfigure(index=c, weight=1) for r in range(3): root.rowconfigure(index=r, weight=1) for r in range(3): for c in range(3): btn = ttk.Button(text=f"(,)") btn.grid(row=r, column=c) root.mainloop()
Поскольку у нас три строки, для упрощения в цикле для каждой строки устанавливаем вес 1. То есть в итоге каждая из трех строк будет занимать треть высоты контейнера (пространство_контейнера / сумму всех весов строк).
Аналогично в цикле для каждого столбца устанавливаем вес 1. То есть в итоге каждый из трех столбец будет занимать треть ширины контейнера.
Отступы
Параметры padx и pady повзвозяют установить отступы по горизонтали и вертикали соответственно от границ ячейки грида до границ виджета, а ipadx и ipady — отступы по горизонтали и вертикали соответственно от границ виджета до его содержимого
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for c in range(3): root.columnconfigure(index=c, weight=1) for r in range(3): root.rowconfigure(index=r, weight=1) for r in range(3): for c in range(3): btn = ttk.Button(text=f"(,)") btn.grid(row=r, column=c, ipadx=6, ipady=6, padx=4, pady=4) root.mainloop()
В данном случае внешние отсуты равны 4 единиц, а внутренние — 6 единицам.
Для параметров padx и pady можно установить отступы с двух сторон в виде списка:
btn.grid(row=r, column=c, ipadx=6, ipady=6, padx=[15, 4], pady=4)
Здесь внешний отступ слева равен 10, а справа — 4 единицам.
Объединение ячеек
Параметр columnspan указывает, столько столбцов, а параметр
rowspan сколько строк должен занимать виджет. То есть с помощью подобных параметров мы можем объединить ячейки.
Растяжение на два столбца:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for c in range(2): root.columnconfigure(index=c, weight=1) for r in range(2): root.rowconfigure(index=r, weight=1) btn1 = ttk.Button(text="button 1") # columnspan=2 - растягиваем на два столбца btn1.grid(row=0, column=0, columnspan=2, ipadx=70, ipady=6, padx=5, pady=5) btn3 = ttk.Button(text="button 3") btn3.grid(row=1, column=0, ipadx=6, ipady=6, padx=5, pady=5) btn4 = ttk.Button(text="button 4") btn4.grid(row=1, column=1, ipadx=6, ipady=6, padx=5, pady=5) root.mainloop()
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for c in range(2): root.columnconfigure(index=c, weight=1) for r in range(2): root.rowconfigure(index=r, weight=1) btn2 = ttk.Button(text="button 2") # rowspan=2 - растягиваем на две строки btn2.grid(row=0, column=1, rowspan=2, ipadx=6, ipady=55, padx=5, pady=5) btn1 = ttk.Button(text="button 1") btn1.grid(row=0, column=0, ipadx=6, ipady=6, padx=5, pady=5) btn3 = ttk.Button(text="button 3") btn3.grid(row=1, column=0, ipadx=6, ipady=6, padx=5, pady=5) root.mainloop()
Выравнивание
Параметр sticky задает выравнивание виджета в ячейке, если размер ячейки больше размера этого виджета. Этот параметр может принимать следующие значения:
- n : положение вверху по центру
- e : положение в правой части контейнера по центру
- s : положение внизу по центру
- w : положение в левой части контейнера по центру
- nw : положение в верхнем левом углу
- ne : положение в верхнем правом углу
- se : положение в нижнем правом углу
- sw : положение в нижнем левом углу
- ns : растяжение по вертикали
- ew : растяжение по горизонтали
- nsew : растяжение по горизонтали и вертикали
По умолчанию виджет позиционируется по центру ячейки
Наглядно растяжение по вертикали и горизонтали
Стоит отметить, что значение в кавычках для параметра anchor передается в нижнем регистре, без кавычек — в верхнем регистре
Например, растянем виджет по всему пространству ячейки (значение NSEW):
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") for c in range(3): root.columnconfigure(index=c, weight=1) for r in range(3): root.rowconfigure(index=r, weight=1) for r in range(3): for c in range(3): btn = ttk.Button(text=f"(,)") btn.grid(row=r, column=c, ipadx=6, ipady=6, padx=4, pady=4, sticky=NSEW) root.mainloop()
Python tkinter размещение элементов
Для позиционирования виджетов в контейнере применяются различные способы. Один из них представляет вызов у виджета метода pack() . Этот метод принимает следующие параметры:
- expand : если равно True, то виджет заполняет все пространство контейнера.
- fill : определяет, будет ли виджет растягиваться, чтобы заполнить свободное пространство вокруг. Этот параметр может принимать следующие значения: NONE (по умолчанию, элемент не растягивается), X (элемент растягивается только по горизонтали), Y (элемент растягивается только по вертикали) и BOTH (элемент растягивается по вертикали и горизонтали).
- anchor : помещает виджет в определенной части контейнера. Может принимать значения n, e, s, w, ne, nw, se, sw, c, которые являются сокращениями от Noth(север — вверх), South (юг — низ), East (восток — правая сторона), West (запад — левая сторона) и Center (по центру). Например, значение nw указывает на верхний левый угол
- side : выравнивает виджет по одной из сторон контейнера. Может принимать значения: TOP (по умолчанию, выравнивается по верхней стороне контейнера), BOTTOM (выравнивание по нижней стороне), LEFT (выравнивание по левой стороне), RIGHT (выравнивание по правой стороне).
- ipadx : устанавливает отступ содержимого виджета от его границы по горизонтали.
- ipady : устанавливают отступ содержимого виджета от его границы по вертикали.
- padx : устанавливает отступ виджета от границ контейнера по горизонтали.
- pady : устанавливает отступ виджета от границ контейнера по вертикали.
Растяжение виджета
Для растяжения виджета применяется параметру expand передается значение True (или соответствующее число). Причем при отсутствии других параметров позиционирования значение expand=True позволяет поместить виджет по центру:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(expand=True) root.mainloop()
Anchor
Параметр anchor помещает виджет в определенной части контейнера. Может принимать следующие значения:
- n : положение вверху по центру
- e : положение в правой части контейнера по центру
- s : положение внизу по центру
- w : положение в левой части контейнера по центру
- nw : положение в верхнем левом углу
- ne : положение в верхнем правом углу
- se : положение в нижнем правом углу
- sw : положение в нижнем левом углу
- center : положение центру
Схематически это выглядит следующим образом:
Стоит отметить, что значение в кавычках для параметра anchor передается в нижнем регистре, без кавычек — в верхнем регистре
btn.pack(anchor="nw") btn.pack(anchor=NW)
Также стоит отметить, что для некоторых сценариев (например, помещение в нижней части контейнера) может потребоваться указать для параметра expand значение True. Например, поместим кнопку в верхнем левом углу:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(anchor="nw") root.mainloop()
Заполнение контейнера
Параметр fill позволяет заполнить пространство контейнер по вертикали (значение X), по вертикали (значение Y) или по обеим сторонам (значение BOTH). По умолчанию значение NONE, при котором заполнение контейнера отсутствует. Например, заполним все пространство контейнера по горизонтали
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(fill=X) root.mainloop()
Для заполнения контейнера по всем сторонам также требуется установить параметр expand = True
btn.pack(fill=BOTH, expand=True)
Отступы
Параметры padx и pady позволяют указать отступы виджета от границ контейнера:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(anchor="nw", padx=20, pady=30) root.mainloop()
Здесь кнопка смещена относительно верхнего левого угла на 20 единиц вправо и на 30 единиц вниз
Выше устанавливался общий отступ от левой и правой стороны и общий отступ от верхней и нижней кромки контейнера. Поскольку кнопка позиционировалась в верхнем левом углу и имеела небольшие размеры, отступ от нижней и правой кромки контейнера нас не особо интересовали. Однако при желании мы можем задать отдельно два отступа от правой и левой границы и отдельно два отступа от верхней и нижней границ:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(fill=X, padx=[20, 60], pady=30) root.mainloop()
В данном случае отступ слева — 20 единиц, а справа — 60 единиц
Параметры ipadx и ipady позволяют указать отступы содержимого виджета от границ виджета по горизонтали и вертикали соответственно:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click me") btn.pack(expand=True, ipadx=10, ipady=10) root.mainloop()
Позиционирование по стороне
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn1 = ttk.Button(text="BOTTOM") btn1.pack(side=BOTTOM) btn2 = ttk.Button(text="RIGHT") btn2.pack(side=RIGHT) btn3 = ttk.Button(text="LEFT") btn3.pack(side=LEFT) btn4 = ttk.Button(text="TOP") btn4.pack(side=TOP) root.mainloop()
Комбинируя параметры side и fill, можно растянуть элемент по вертикали:
btn1 = ttk.Button(text="CLICK ME") btn1.pack(side=LEFT, fill=Y)