Подробный обзор по "Tkinter"

Подробный обзор по "Tkinter"

Python и 1000 программ

Tkinter – это пакет для Python, предназначенный для работы с библиотекой Tk. Библиотека Tk содержит компоненты графического интерфейса пользователя (graphical user interface – GUI). Эта библиотека написана на языке программирования Tcl.


Под графическим интерфейсом пользователя (GUI) подразумеваются все что вы видите в программе, обычный текст, кнопки, вкладки и т.д, которые вы видите на экране. Благодаря им вы можете управлять программой так, как она была предусмотрена. По стандарту их называют виджетами (widgets).


В настоящее время почти все приложения, которые создаются для конечного пользователя, имеют GUI. Редкие программы, подразумевающие взаимодействие с человеком, остаются консольными.


Существует множество библиотек GUI, среди которых Tk не самый популярный инструмент, хотя с его помощью написано немало проектов. Он был выбран для Python по-умолчанию. Установочный файл интерпретатора Питона обычно уже включает пакет tkinter в составе стандартной библиотеки, это значит что вам не нужно прибегать к pip.


Tkinter можно представить как переводчик с языка Python на язык Tcl. Вы пишете программу на Python, а код модуля tkinter переводит ваши инструкции на язык Tcl, который понимает библиотека Tk.


Программы с графическим интерфейсом пользователя событийно-ориентированные. Вы уже должны иметь представление о структурном и желательно объектно-ориентированном программировании. Событийно-ориентированное ориентировано на события. То есть та или иная часть программного кода начинает выполняться лишь тогда, когда случается то или иное событие.


Событийно-ориентированное программирование базируется на объектно-ориентированном и структурном. Даже если мы не создаем собственных классов и объектов, то все-равно ими пользуемся. Все виджеты – объекты, порожденные встроенными классами.


События бывают разными. Сработал временной фактор, кто-то кликнул мышкой или нажал Enter, начал вводить текст, переключил радиокнопки, прокрутил страницу вниз и т. д. Когда случается что-то подобное, то, если был создан соответствующий обработчик, происходит срабатывание определенной части программы, что приводит к какому-либо результату.




Можно импортировать отдельные классы, что делается редко. В данной статье мы будем использовать выражение from tkinter import *.


Если необходимо, узнать установленную версию Tk можно через константу TkVersion:




Создать главное окно.
Создать виджеты и выполнить конфигурацию их свойств (опций).
Определить события, то есть то, на что будет реагировать программа.
Описать обработчики событий, то есть то, как будет реагировать программа.
Расположить виджеты в главном окне.
Запустить цикл обработки событий.


Последовательность не обязательно такая, но первый и последний пункты всегда остаются на своих местах. Посмотрим все это в действии.


В современных операционных системах любое пользовательское приложение заключено в окно, которое можно назвать главным, так как в нем располагаются все остальные виджеты. Объект окна верхнего уровня создается от класса Tk модуля tkinter. Переменную, связываемую с объектом, часто называют root (корень):



Пусть в окне приложения располагаются текстовое поле, метка и кнопка. Данные объекты создаются от классов Entry, Label и Button модуля tkinter. Мы сразу сконфигурируем некоторые их свойства с помощью передачи аргументов конструкторам этих классов:



Устанавливать свойства объектов не обязательно при их создании. Существуют еще пара способов, с помощью которых это можно сделать после.


Первым аргументом в конструктор виджета передается виджет-хозяин, то есть тот, на котором будет располагаться создаваемый. В случае, когда элементы GUI помещаются непосредственно на главное окно, родителя можно не указывать. То есть в нашем примере мы можем убрать root:


Однако виджеты не обязательно располагаются на root'е. Они могут находиться на других виджетах, и тогда указывать "мастера" необходимо.


Пусть в программе текст, введенный человеком в поле, при нажатии на кнопку разбивается на список слов, слова сортируются по алфавиту и выводятся в метке. Выполняющий все это код надо поместить в функцию:


У функций, которые вызываются при наступлении события с помощью метода bind, должен быть один параметр. Обычно его называют event, то есть "событие".


В нашей функции с помощью метода get из поля забирается текст, представляющий собой строку. Она преобразуется в список слов с помощью метода split. Потом список сортируется. В конце изменяется свойство text метки. Ему присваивается строка, полученная из списка с помощью строкового метода join.


Теперь необходимо связать вызов функции с событием:

В данном случае это делается с помощью метода bind. Ему передается событие и функция-обработчик. Событие будет передано в функцию и присвоено параметру event. Здесь событием является щелчок левой кнопкой мыши, что обозначается строкой '<Button-1>'.


В любом приложении виджеты не разбросаны по окну как попало, а организованы, интерфейс продуман до мелочей и обычно подчинен определенным стандартам. Пока расположим элементы друг под другом с помощью наиболее простого менеджера геометрии tkinter – метода pack:


Метод mainloop экземпляра Tk запускает главный цикл обработки событий, что в том числе приводит к отображению главного окна со всеми "упакованными" на нем виджетами:

Полный код программы:

В результате выполнения данного скрипта появляется окно, в текстовое поле которого можно ввести список слов, нажать кнопку и получить его отсортированный вариант:



Попробуем теперь реализовать в нашей программе объектно-ориентированный подход. Это необязательно, но нередко бывает удобным. Пусть группа из метки, кнопки и поля представляет собой один объект, порождаемый от класса Block. Тогда в основной ветке программы будет главное окно, объект типа Block и запуск окна. Поскольку блок должен быть привязан к главному окну, то неплохо бы передать в конструктор класса окно-родитель:


Теперь напишем сам класс Block:

Здесь виджеты являются значениями полей объекта типа Block, функция-обработчик события нажатия на кнопку устанавливается не с помощью метода bind, а с помощью свойства кнопки command. В этом случае в вызываемой функции не требуется параметр event. В метод мы передаем только сам объект.


Однако, если код будет выглядеть так, то необходимости в классе нет. Смысл появится, если нам потребуется несколько или множество похожих объектов-блоков. Допустим, нам нужно несколько блоков, состоящих из метки, кнопки, поля. Причем у кнопки каждой группы будет своя функция-обработчик клика.


Тогда можно передавать значения для свойства command в конструктор. Значение будет представлять собой привязываемую к кнопке функцию-обработчик события. Полный код программы:


Выражение getattr(self, func), где вместо func подставляется строка 'str_to_sort' или 'str_reverse', преобразуется в выражение self.str_to_sort или self.str_reverse.


При выполнения этого кода в окне будут выведены два однотипных блока, кнопки которых выполняют разные действия.


Класс можно сделать более гибким, если жестко не задавать свойства виджетов, а передавать значения как аргументы в конструктор, после чего присваивать их соответствующим опциям при создании объектов.

Report Page