Ключевым строительным блоком в графическом приложении являются различные элементов управления, с которыми взаимодействует пользователь, как кнопки, метки, поля ввода. В Tkinter имеется богатая палитра различных элементов управления, которые называются виджетами. Основные из них:
Button: кнопка
Label: текстовая метка
Entry: однострочное текстовое поле
Text: многострочное текстовое поле
Checkbutton: флажок
Radiobutton: переключатель или радиокнопка
Frame: фрейм, который организует виджеты в группы
Listbox: список
Combobox: выпадающий список
Menu: элемент меню
Scrollbar: полоса прокрутки
Treeview: позволяет создавать древовидные и табличные элементы
Scale: текстовая метка
Spinbox: список значений со стрелками для перемещения по элементам
Progressbar: текстовая метка
Canvas: текстовая метка
Notebook: панель вкладок
Tkinter предоставляет виджеты в двух вариантах: виджеты, которые располагаются непосредственно в пакете tkinter, и виджеты из пакета tkinter.ttk. С одной стороны, оба пакета предоставляют практически одни и те же виджеты, например, виджет Button есть в обоих пакетах. Но с другой стороны, ttk предоставляет чуть больше функциональности по настройке виджетов, в частности, по их стилизации. И считается, что виджеты из ttk несколько современнее, чем стандартные, в то же время с ttk, возможно, чуть сложнее работать. Что именно использовать остается на выбор разработчика.
Рассмотрим разницу на примере виджета Button. Сначала посмотрим на стандартный виджет Button из общего пакета tkinter:
from tkinter import *
root = Tk()
root.title("METANIT.COM")
root.geometry("250x200")
btn = Button(text="Click") # создаем кнопку из пакета tkinter
btn.pack() # размещаем кнопку в окне
root.mainloop()
Теперь посмотрим на примере кнопки из пакета ttk:
from tkinter import *
from tkinter import ttk # подключаем пакет ttk
root = Tk()
root.title("METANIT.COM")
root.geometry("250x200")
btn = ttk.Button(text="Click") # создаем кнопку из пакета ttk
btn.pack() # размещаем кнопку в окне
root.mainloop()
По сути мы создаем ту же самую кнопку с той же надписью, однако ее внешний вид будет несколько иной:
В дальнейшем я буду ориентироваться прежде всего на виджеты из пакета ttk, но перейти на стандартные виджеты не составит особого труда.
Виджет обладает набором параметров, которые позволяют настроить его внешний вид и поведение. У каждого виджета свой набор параметров. Обычно параметры задаются через конструктор. Например, в примере выше
у кнопки устанавливался параметр text, который задает текст на кнопке:
ttk.Button(text="Click") # устанавливаем параметр text
Но обращаться к параметрам можно и вне конструктора, используя имя переменной виджета и синтаксис словарей:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("METANIT.COM")
root.geometry("250x150")
btn = ttk.Button()
btn.pack()
# устанавливаем параметр text
btn["text"]="Send"
# получаем значение параметра text
btnText = btn["text"]
print(btnText)
root.mainloop()
Для изменения параметров виджета также можно использовать метод config(), в который передаются параметры и их значения:
btn = ttk.Button() btn.pack() # устанавливаем параметр text btn.config(text="Send Email")
Для получения информации о виджете можно использовать ряд его атрибутов. Рассмотрим некоторые из них:
winfo_class: возвращает класс виджета, например, для кнопки это класс TButton
winfo_children: возвращает для текущего виджета список вложенных виджетов
winfo_parent: возвращает родительский виджет
winfo_toplevel: возвращает окно, которое содержит данный виджет
winfo_width и winfo_height: текущая ширина и высота виджета
winfo_reqwidth и winfo_reqheight: запрошенная виджетом ширина и высота
winfo_x и winfo_y: x и y координаты верхнего левого угла виджета относительно родительского элемента
winfo_rootx и winfo_rooty: x и y координаты верхнего левого угла виджета относительно экрана
winfo_viewable: указывает, отображается ли виджет или скрыт
Например, получим информацию о всех виджетах в окне:
from tkinter import *
root = Tk()
root.title("METANIT.COM")
root.geometry("250x200")
btn = Button(text="Hello")
btn.pack()
def print_info(widget, depth=0):
widget_class=widget.winfo_class()
widget_width = widget.winfo_width()
widget_height = widget.winfo_height()
widget_x = widget.winfo_x()
widget_y = widget.winfo_y()
print(" "*depth + f"{widget_class} width={widget_width} height={widget_height} x={widget_x} y={widget_y}")
for child in widget.winfo_children():
print_info(child, depth+1)
root.update() # обновляем информацию о виджетах
print_info(root)
root.mainloop()
Здесь определена функция print_info(), которая в качестве параметров получает виджет, информацию о котором надо вывести на консоль, и уровень в визуальной иерархии элементов (depth).
В самой функции для виджета выводим информацию о классе, ширине, высоте и координатах Х и Y, а также для каждого вложенного виджета рекурсивно вызываем эту же функцию.
Чтобы установленные размеры и позиции были применены к виджетам до вызыва root.mainloop(), вызываем метод root.update()
В данном случае визуальная иерархия виджетов не такая глубокая - всего два элемента - окно (Tk) и кнопка (Button), соответственно консольный вывод будет следуюшим:
Tk width=250 height=200 x=104 y=104 Button width=39 height=26 x=105 y=0