Менеджер геометрии сетки Tkinter Grid в Python с примерами
Менеджер геометрии Tkinter Grid размещает виджет в окне.
- Что такое менеджер геометрии сетки Tkinter Grid?
- Настройка сетки
- Размещение виджета в сетке
- Sticky
- Отступ
- Пример Tkinter grid
Что такое менеджер геометрии сетки Tkinter Grid?
Менеджер геометрии сетки Tkinter Grid в Python использует концепции строк и столбцов для упорядочивания виджетов.
Ниже показана сетка, состоящая из четырех строк и трех столбцов:
Каждая строка и столбец в сетке идентифицируются индексом. По умолчанию первая строка имеет индекс ноль, вторая строка имеет индекс один и т. д. Аналогично, столбцы в сетке имеют индексы ноль, один, два и т. д.
Индексы строк и столбцов в сетке не обязательно должны начинаться с нуля. Кроме того, индексы строк и столбцов могут иметь пробелы.
Например, у вас может быть сетка, индексы столбцов которой равны 1, 2, 10, 11 и 12. Это полезно, если вы планируете позже добавить больше виджетов в середину сетки.
Пересечение строки и столбца называется ячейкой. Ячейка — это область, в которой можно разместить виджет. Ячейка может содержать только один виджет. Если разместить два виджета в ячейке, они будут друг над другом.
Чтобы разместить несколько виджетов в ячейке, используйте Frame или LabelFrame, чтобы обернуть виджеты и поместить Frame или LabelFrame в ячейку.
Ширина столбца зависит от ширины виджета, который он содержит. Аналогично, высота строки зависит от высоты виджетов, содержащихся в строке.
Строки и столбцы могут объединяться. Ниже показана сетка, имеющая ячейку(1,1), охватывающую два столбца, и ячейку(0,2), охватывающую две строки:
Настройка сетки
Перед размещением виджетов в сетке вам необходимо настроить строки и столбцы сетки.
Tkinter предоставляет два метода настройки строк и столбцов сетки:
container.columnconfigure(index, weight) container.rowconfigure(index, weight)
Метод columnconfigure() настраивает index столбца сетки.
weight определяет, какую ширину займет столбец по отношению к другим столбцам. Например, столбец с weight 2 будет в два раза шире столбца с весом 1.
Размещение виджета в сетке
Чтобы разместить виджет в сетке, используйте метод виджета grid():
widget.grid(**options)
Метод grid() имеет следующие параметры:
Параметры | Значение |
---|---|
column | Индекс столбца, в котором вы хотите разместить виджет. |
row | Индекс строки, в которую вы хотите поместить виджет. |
rowspan | Установите количество смежных строк, которые может охватывать виджет. |
columnspan | Установите количество смежных столбцов, которые может охватывать виджет. |
sticky | Если ячейка больше виджета, параметр «sticky» указывает, к какой стороне виджет должен прикрепляться и как распределять дополнительное пространство внутри ячейки, которое не занято виджетом при его исходном размере. |
padx | Добавьте внешние отступы над и под виджетом. |
pady | Добавьте внешние отступы слева и справа от виджета. |
ipadx | Внутренние отступы внутри виджета с левой и правой сторон. |
ipady | Внутренние отступы внутри виджета сверху и снизу. |
Sticky
По умолчанию, если ячейка больше содержащегося в ней виджета, менеджер геометрии сетки размещает виджет в центре ячейки по горизонтали и вертикали.
Чтобы изменить это поведение по умолчанию, можно использовать параметр sticky. Параметр sticky указывает, к какому краю ячейки должен прилипать виджет.
Значение sticky имеет следующие допустимые значения:
Липкий | Описание |
---|---|
N | Север или по центру сверху |
S | Юг или по центру снизу |
E | Восток или по центру справа |
W | Запад или по центру слева |
NW | Северо-запад или верхний левый угол |
NE | Северо-восток или верхний правый угол |
SE | Юго-Восток или нижний правый угол |
SW | Юго-запад или нижний левый угол |
NS | NS растягивает виджет по вертикали. Однако по горизонтали виджет остается центрированным. |
EW | EW растягивает виджет по горизонтали. Однако по вертикали он остается центрированным. |
Если вы хотите разместить виджет в углу ячейки, вы можете использовать клавиши N, S, E и W.
В следующем примере показано, как расположить виджет, если параметр sticky установлен на N:
Если вы хотите расположить виджет по центру одной из сторон ячейки, вы можете использовать NW(вверху слева), NE(вверху справа), SE(внизу справа) и SW(внизу слева).
В следующем примере показано, как расположить виджет с параметром N, установленным на NW:
NS растягивает виджет по вертикали. Однако он оставляет виджет центрированным по горизонтали:
EW растягивает виджет по горизонтали. Однако он оставляет виджет центрированным по вертикали:
Отступ
Для добавления отступов между ячейками сетки используйте параметры padx и pady. Padx и pady — это внешние отступы:
grid(column, row, sticky, padx, pady)
Чтобы добавить отступы в сам виджет, используйте параметры ipadx и ipady. Ipadx и ipady — это внутренние отступы:
grid(column, row, sticky, padx, pady, ipadx, ipady)
Внутренние и внешние отступы по умолчанию равны нулю.
Пример Tkinter grid
В этом примере мы воспользуемся менеджером геометрии сетки для разработки экрана входа в систему следующим образом:
Экран входа использует сетку с двумя столбцами и тремя строками. Кроме того, второй столбец в три раза шире первого:
Ниже показано полное окно входа в систему:
import tkinter as tk from tkinter import ttk # root window root = tk.Tk() root.geometry("240x100") root.title('Login') root.resizable(0, 0) # configure the grid root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=3) # username username_label = ttk.Label(root, text="Username:") username_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5) username_entry = ttk.Entry(root) username_entry.grid(column=1, row=0, sticky=tk.E, padx=5, pady=5) # password password_label = ttk.Label(root, text="Password:") password_label.grid(column=0, row=1, sticky=tk.W, padx=5, pady=5) password_entry = ttk.Entry(root, show="*") password_entry.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5) # login button login_button = ttk.Button(root, text="Login") login_button.grid(column=1, row=3, sticky=tk.E, padx=5, pady=5) root.mainloop()
Как это работает.
- Сначала используйте метод columnconfigure(), чтобы задать вес первого и второго столбцов сетки. Ширина второго столбца в три раза больше ширины первого столбца.
root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=3)
- Во-вторых, поместите метку имени пользователя в первый столбец, а запись имени пользователя — во второй столбец первой строки сетки:
username_label = ttk.Label(root, text="Username:") username_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5) username_entry = ttk.Entry(root, textvariable=username) username_entry.grid(column=1, row=0, sticky=tk.E, padx=5, pady=5
- В-третьих, разместите метку пароля и запись в первом и втором столбцах второй строки:
password_label = ttk.Label(root, text="Password:") password_label.grid(column=0, row=1, sticky=tk.W, padx=5, pady=5) password_entry = ttk.Entry(root, textvariable=password, show="*") password_entry.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
- Наконец, разместите кнопку входа в третью строку. Поскольку ее параметр sticky установлен на E, кнопка выравнивается по правому краю третьей строки.
login_button = ttk.Button(root, text="Login") login_button.grid(column=1, row=3, sticky=tk.E, padx=5, pady=5)
Ниже показана та же программа. Однако вместо этого она использует объектно-ориентированное программирование:
import tkinter as tk from tkinter import ttk class App(tk.Tk): def __init__(self): super().__init__() self.geometry("240x100") self.title('Login') self.resizable(0, 0) # configure the grid self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=3) self.create_widgets() def create_widgets(self): # username username_label = ttk.Label(self, text="Username:") username_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5) username_entry = ttk.Entry(self) username_entry.grid(column=1, row=0, sticky=tk.E, padx=5, pady=5) # password password_label = ttk.Label(self, text="Password:") password_label.grid(column=0, row=1, sticky=tk.W, padx=5, pady=5) password_entry = ttk.Entry(self, show="*") password_entry.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5) # login button login_button = ttk.Button(self, text="Login") login_button.grid(column=1, row=3, sticky=tk.E, padx=5, pady=5) if __name__ == "__main__": app = App() app.mainloop()