Все записи автора knzroot

Урок 1. Простейшее приложение с использованием Tkinter

Вернуться к общему содержанию «Python. Графическая библиотека tkinter для начинающих».

Так как Tkinter представляет собой объектно-ориентированный интерфейс к прикладному оконному интерфейсу операционной системы, то будет нелишним вспомнить основную терминологию ООП (Объектно-Ориентированного Программирования) в упрощенном виде.

  • Класс или Тип — это описание некоторого набора данных и возможных действий с этими данными.
  • Объекты — это «живые» экземпляры, созданные по описаниям класса. Как правило, экземпляры классов связывают с переменными языка.
  • — Данные, описанные в классе, называются членами класса.
  • — Действия, описанные в классе и выполняемые, как правило, над его данными, называются методами класса.
  • Метод класса выполняемый при создании класса (для начальной инициализации его членов) называется конструктором класса.

Такой краткий обзор терминологии является не совсем точным, с учетом тонкостей реализации ООП в языке Python, но, тем не менее, он вполне достаточен для дальнейшего понимания материала.

Минимальное приложение, демонстрирующее работу с модулем tkinter состоит всего из трех строчек.

from tkinter import *
x = Tk()
x.mainloop()

Первая строка импортирует все объявленное в модуле tkinter в пространство имен текущего модуля Python.

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

Чтобы использовать возможности класса Tk необходимо создать объект — экземпляр данного класса. Вторая строка нашей программы, как раз создает экземпляр класса Tk и связывает его с переменной x.

Теперь, переменная класса Tk создана. Что будет если запустить такую программу из двух строчек? Можно попробовать. Увидим ли мы окно приложения?

Нет, к сожалению, никакого окна мы пока не увидим! Чтобы окно приложения появилось на экране, необходимо запустить оконную функцию, обрабатывающую события окна приложения.

Именно третья строка нашей программы регистрирует и запускает в операционной системе оконную функцию приложения. В этой строке, мы через объект x, который является посредником для обращения к операционной системе, мы вызываем метод mainloop() (переводится с английского как «главная петля» или «главный цикл»). Именно этот метод класса Tk регистрирует в операционной системе оконную функцию и запускает цикл обработки событий, поступающих от операционной системы.

Пока, этот набор событий, которые обрабатывает такое «пустое» оконное приложение очень небольшое — мы можем поменять размеры окна, свернуть или развернуть окно, и, наконец, закрыть.

Запустим нашу программу из трех строчек и убедимся в том, что теперь у нашего приложения появилось окно и это окно управляется стандартным способом — меняет размеры, может быть свернуто, развернуто или закрыто.

Термин «оконная функция» относится к прикладному интерфейсу (API — Application Programming Interface) оконных графических интерфейсов пользователя. С точки зрения этих интерфейсов через оконную функцию, приложение получает события от операционной системы. Например, это события от мыши, который возникают над прямоугольной областью окна приложения, или от клавиатуры, если окно приложения находится в фокусе. Важно понимать, что само понятие «окна» для оконного интерфейса связано не столько с прямоугольной областью на экране, сколько, именно, с оконной функцией приложения, так как не все приложения имеют видимое представление. В нашем случае, метод mainloop() класса Tk не является оконной функцией в строгом понимании этого термина, но имеет прямое отношение к циклу обработки событий связанных с этой функцией, сокрытой в реализации модуля Tkinter.

Чтобы лучше понять работу метода mainloop() добавим вызов функции print() после него. Запустим получившуюся программу и посмотрим, когда отработает печать из функции print().

from tkinter import *
x = Tk()
x.mainloop()
print("Done")

По результату этого эксперимента мы видим, что метод mainloop() завершает работу тогда, когда мы, средствами операционной системы пошлем событие закрытия окна приложения.

Из этого простого эксперимента следует очень важный факт — сначала следует полностью выстроить интерьер нашего окна, и настроить все обработчики событий, а уже потом запускать метод mainloop().

Теперь, немного расширим наше простейшее приложение, указав заголовок (title) его окна и настроив желаемую начальную геометрию (geometry) окна.

from tkinter import *
x = Tk()

x.title("Hello world!")
x.geometry("600x300")

x.mainloop()

Обратите внимание на строковый вид параметра, передаваемого в метод geometry(). В указанном примере, задается окно размером 600 пикселей по горизонтали и 300 пикселей по вертикали.

В завершении этого урока еще раз обратим внимание на используемую форму импорта. Используя такой способ импорта символов нам не понадобится квалифицировать именем модуля обращение к каждому символу из этого модуля. Чтобы стало понятнее приведем фрагмент исходной программы с другой формой импорта.

import tkinter

x = tkinter.Tk()

x.mainloop()

Для такого простого кода форма импорта особенного значения не имеет. Однако, уже даже небольшие усложнения интерьера главного окна приводят к утомительным затратам на частую квалификацию используемых символов модуля tkinter.

Однако, использование формы импорта в виде «from tkinter import *» не рекомендуется и отслеживается политикой S2208: «Wildcard imports should not be used (python:S2208)». Причиной этому являются трудноуловимые коллизии, которые могут возникнуть при использовании одинаковых символов в разных используемых модулях.

Компромиссом в вопросе выбора формы импорта может оказаться форма импорта с использованием псевдонима (alias) для импортируемого модуля. При этом, в качестве псевдонима следует выбрать какое-нибудь более короткое имя.

import tkinter as tk

x = tk.Tk()

x.mainloop()