Tkinter - это пакет модулей Python для создания приложений с графическим интерфейсом. Tkinter используется в Python по умолчанию. В уроке рассматривается последовательность шагов создания GUI-программы. То есть импорт, создание окна, установка свойств, событий и так далее.
Под графическим интерфейсом пользователя подразумеваются все те окна, кнопки, текстовые поля для ввода, списки, флажки и другие элементы, которые вы видите на экране, открывая какое-либо приложение. Через них вы взаимодействуете с программой и управляете ею. Все эти элементы интерфейса называются виджетами.
В данный момент времени почти все приложения, которые создаются для конечного пользователя, имеют GUI. Редкие программы, которые подразумевают в себе взаимодействие с человеком, остаются консольными.
Существует множество библиотек GUI, среди которых Tkinter является не самым популярным инструментом, хотя с его помощью его написано немало проектов. Он выбран для Python по умолчанию. Установочный файл интерпретатора обычно уже включает пакет tkinter в составе стандартной библиотеки python.
Tkinter можно представить как переводчик с языка Python на язык Tcl. Вы пишете программу на Python, а код модуля tkinter переводит ваши инструкции на язык Tcl, который понимает библиотека Tkinter.
Программы с графическим интерфейсом пользователя событийно-ориентированные, то есть существует та или иная часть программного кода начинает выполняться лишь тогда, когда случается какое-либо событие.
Событийно-ориентированное программирование строиться на объектно-ориентированном. Даже если мы не будем разрабатывать новые классы, то мы все равно обязательно будем пользоваться теми, что есть в библиотеке tkinter. Все виджеты - это те или иные объекты-экземпляры, создаваемые от встроенных классов.
События бывают разными. Например, завершилась загрузка, пришло сообщение или кто-то кликнул мышкой или нажал Enter. Когда случается что-либо подобное, то, если был создан обработчик для данного типа события, происходит выполнение определенной части программы, что приводит к результату.
Tkinter импортируется стандартно для модуля Python:
Чтобы написать GUI-программу, надо выполнить следующие условия:
- Создать главное окно.
- Создать виджеты и выполнить конфигурацию свойств.
- Определить события. Это значит то, на что будет реагировать наша программа.
- Описать обработчики событий. Это значит как будет реагировать наша программа.
- Расположить виджеты в главном окне.
- Запустить цикл обработки наших событий.
Последовательность не обязательно будет выглядеть именно так, но первый и последний пункты всегда будут оставаться на своих местах.
В современных операционных системах любое пользовательское приложение заключено в окно, которое называется главным, так как в нем располагаются все остальные виджеты. Объект окна верхнего уровня создается от модуля Tkinter. Переменную, связываемую с объектом, часто называют root (в переводе - корень):
Пусть в окне приложения располагаются текстовое поле, метка и кнопка. Данные объекты создаются от классов Entry, Label и Button модуля tkinter. Давайте выполним конфигурацию некоторых свойств с помощью передачи аргументов, конструкторам этих классов:
Устанавливать свойства объектов не обязательно при их создании. Существуют еще способы, с помощью которых можно сделать тоже самое после.
Первым аргументом в конструктор виджета передается виджет-хозяин, то есть тот, на котором будет располагаться наш создаваемый виджет. В случае, когда элементы GUI помещаются непосредственно на главное окно, родителя можно не указывать. То есть в нашем примере мы можем убрать root. Например:
Хотя виджеты не обязательно располагаются на root. Они также могут находиться на других виджетах, и тогда указывать "главного" необходимо.
Пусть в программе текст, введенный человеком в поле, при нажатии на кнопку разбивается на список слов, слова сортируются по алфавиту и выводятся в так называемой метке. Выполняющий все это код надо поместить в функцию:
Функций, которые вызываются при наступлении события с помощью метода bind, должен быть один параметр. Обычно его называют event, то есть в переводе - событие.
В нашей функции с помощью метода get из поля забирается текст, который представляет собой строку. Она преобразуется в список слов с помощью метода split, а уже потом список сортируется. В конце изменяется свойство text метки. Ему присваивается строка, полученная из списка с помощью метода join.
Теперь необходимо связать вызов функции с нашим событием. Для этого нам необходимо с помощью метода bind, передать событие и функцию-обработчик. Событие будет передано в функцию и присвоено параметру event:
В любом приложении виджеты не разбросаны по окну как попало, а организованы, интерфейс продуман до мелочей и обычно подчинен определенным стандартам. Пока расположим элементы друг под другом с помощью наиболее простого менеджера геометрии tkinter и метода pack:
Метод mainloop экземпляра tkinter запускает главный цикл обработки событий, для того чтобы число приводить к отображению главного окна со всеми "упакованными" на нем виджетами:
Теперь давайте все наши действия преобразуем в одну целую программу:
В результате выполнения данного кода появляется окно, в текстовое поле которого можно ввести список слов, нажать кнопку и получить его отсортированный вариант:
Теперь давайте реализуем в нашей программе ООП. Это необязательно, но 'это позволяет нам объединить вместе виджет и функции, которые обрабатывают связанные с ним события, что более верно в нашей ситуации. В этом случае функции становятся методами.
Группа из метки, кнопки и поля будут представлять собой один объект, порождаемый от класса Block. Тогда в основной ветке программы будет главное окно, объект типа Block и запуск окна. Поскольку блок должен быть привязан к главному окну, то стоило бы передать в конструктор класса окно-родитель:
Теперь напишем наш класс Block:
Виджеты являются значениями полей объекта типа Block, функция-обработчик события нажатия на кнопку устанавливается с помощью свойства кнопки command. В этом случае в вызываемой функции не обязателен параметр event. В метод мы передаем только сам объект.
Больший смысл в определении собственного класса появляется, когда требуется несколько или множество похожих объектов-блоков. Например предложим, что нам нужно несколько блоков, состоящих из метки, кнопки, поля. Причем у кнопки каждой группы будет своя функция-обработчик клика.
Тогда можно передавать значения для свойства command в конструктор. Значение будет представлять собой привязываемую к кнопке функцию-обработчик события.
Давайте теперь объединим все написанное ранее и напишем полный код с нашего урока:
Выражение getattr(self, func), где за счет func подставляется строка 'str_to_sort' или 'str_reverse', преобразуется в выражение self.str_to_sort или self.str_reverse.
При запуске нашего кода в окне будут выведены два однотипных блока, кнопки которых будут выполнять разные действия.
На этом урок подошел к концу.
Подписывайтесь на канал, здесь каждый день появляются много полезных статей на python.
Все коды с уроков и сами уроки вы можете найти в моем telegram канале. Также каждый день на канале появляются полезные и эффективные фишки.