Урок 2. Виджеты в Tkinter
Вернуться к общему содержанию «Python. Графическая библиотека tkinter для начинающих».
Ниже приведен текст, составленный по мотивам перевода английской документации, взятой с оригинального ресурса https://tkdocs.com/tutorial/concepts.html#widgets. Посетите оригинал, чтобы посмотреть на картинки, соответствующие тексту.
Виджеты представляют собой все то, что вы видите внутри главного окна приложения, включая и само главное окно.
В Tkinter можно выделить две группы виджетов.
- Базовые виджеты — размещены относятся к модулю tkinter непосредственно.
- Дополнительные виджеты — размещены в стилизованном модуле tkinter.ttk.
Ниже приведен список наиболее часто используемых виджетов библиотеки Tkinter.
- Кнопки (объекты класса Button, см. описание Button, см. пример использования Button)
- Однострочные поля ввода текста (объекты класса Entry, см. описание Entry, см. пример использования Entry)
- Метки (нередактируемый текст или картинка) (объекты класса Label, см. описание Label, см. пример использования Label)
- Фреймы (объекты класса Frame, см. описание Frame, см. пример использования Frame)
- Флажки (объекты класса Checkbutton, см. описание Checkbutton, см. пример использования Checkbutton)
- Радиокнопки (одна из набора) (объекты класса Radiobutton, см. описание Radiobutton, см. пример использования Radiobutton)
- Списки (объекты класса Listbox, см. описание Listbox, см. пример использования Listbox)
- Скроллеры (полосы горизонтальной и вертикальной прокрутки областей) (объекты класса Scrollbar, см. описание Scrollbar, см. пример использования Scrollbar)
- Многострочные текстовые области (объекты класса Text, см. описание Text, см. пример использования Text)
- Области для произвольного рисования с набором инструментов для 2D-графики (объекты класса Canvas, см. описание Canvas, см. пример использования Canvas )
- Виджеты tkinter.ttk (import tkinter.ttk as ttk):
- Деревья (иерархические представления данных) (объекты класса Treeview, см. описание Treeview, см. пример использования Treeview)
- Выпадающие списки (объекты класса Combobox, см. описание Combobox, см. пример использования Combobox)
- Индикаторы прогресса (объекты класса Progressbar, см. описание Progressbar, см. пример использования Progressbar)
В терминологии операционных систем с оконным интерфейсом, виджеты часто называют «элементами управления», а, иногда, и просто «окнами» (последнее часто встречается в документации по Tk).
Такая перегрузка для термина «окно» связана с тем, что, как уже говорилось в предыдущих главах, «окно», с точки зрения прикладного интерфейса оконной системы есть не прямоугольная область на экране, а оконная функция, связанная с набором событий, которое это окно обрабатывает. Как уже говорилось, не каждое оконное приложение связано с видимой прямоугольной областью на экране, поэтому, «окно», это не совсем «виджет». Виджетами являются только те окна, которые имеют видимое представление на экране.
Приложение с оконным графическим интерфейсом состоит из большого множества таких «окон» или «виджетов», начиная с главного окна приложения, на котором слоями размещаются другие, более мелкие окна, которые мы и будем называть виджетами.
Такая слойная иерархия, берущая свое начало от главного окна приложения, образует, так называемый, Z-порядок, название которого подчеркивает размещение слоев по Z-координате, ноль которой находится в плоскости главного окна приложения. На картинке ниже отображена система координат, используемая в концепции построения оконных систем. Плоскость XY, как раз соответствует системе координат окна: X — горизонтальная координата окна, растущая слева направо, а Y — вертикальная координата окна, растущая сверху вниз.
При построении графического интерфейса приложения перед разработчиком стоит задача создания и размещения виджетов в иерархической зависимости (или, в Z-порядке), начиная с главного окна приложения. Главное окно, поэтому, часто называют корневым окном (root window) или корневым виджетом (root widget) приложения.
Создание виджета, с точки зрения разработчика, представляет собой создание экземпляра нужного класса виджета, например, класса Button или класса Frame. При этом, первым параметром передаваемым в конструктор виджета всегда является ссылка на родительский виджет. Родительским называется виджет в теле которого размещается создаваемый виджет. Родительский виджет всегда находится, в Z-порядке ниже создаваемого.
Приведем простейший пример построения такой иерархии, где поверх главного окна будет размещен виджет Frame, а поверх виджета Frame будут размещены две кнопки (объекты класса Button).
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
a = tk.Button(frame)
b = tk.Button(frame)
frame.pack()
a.pack()
b.pack()
root.mainloop()
В приведенном примере умышленно не используются «лишние» параметры, которые, обычно, применяются при создании и размещении виджетов, чтобы не перегружать восприятие кода тем, что еще не было разъяснено.
Обратите внимание на строки 9-11 приведенного выше примера. Созданный виджет не появляется автоматически в области своего родителя. Чтобы это произошло, надо определиться с геометрией размещения виджета.
В свою очередь, геометрия размещения виджета определяется выбором стратегии размещения. Стратегии основаны на менеджерах размещения — специальных алгоритмах, некоторые из которых не только вычисляют требуемые размеры и координаты размещения укладываемых виджетов, но и пересчитывают их при изменении размеров родительского, или соседнего виджетов.
Для библиотеки Tkinter реализованы три менеджера размещения. Доступ к ним выполняется через методы pack(), grid() и place().
- Метод pack() реализован для каждого виджета. Определяет геометрию виджета на основе атрибутов относительного размещения. См. примеры работы с pack().
- Метод grid() реализован в специальном виджете-контейнере Frame. Представляет поверхность родительского виджета в виде сетки, в ячейки которой и выполняется укладка виджетов. См. примеры работы с grid().
- Метод place() реализован для каждого виджета. Используется для покоординатного размещения виджетов внутри координатной системы своего родительского виджета. Такой способ размещения, в большинстве случаев, будет неудачным решением, которое не сможет автоматически отработать изменение размеров как родительского виджета, так и соседних виджетов. См. примеры работы с place().