Transcription
Всем привет!
Следующий пакет Python, с которым мы познакомимся, позволяет дополнять программы графическими компонентами или виджетами: окнами, кнопками, текстовыми полями и т.д. Совокупность виджетов программы формирует графический интерфейс пользователя. Одним из пакетов, с помощью которых создаётся графический интерфейс, является пакет tkinter. Именно об этом пакете пойдёт речь в данном уроке.
Пакет tkinter входит в состав стандартной библиотеки Python. Это означает следующее. Во-первых, в отличие от предыдущих рассмотренных пакетов, tkinter не нужно устанавливать. Во-вторых, подробная информация об этом пакете размещена в официальной документации. Ссылку на эту страницу найдёте в описании данного видео.
Приступим к изучению основ пакета tkinter. Главным виджетом графического интерфейса при работе с tkinter является окно. Окно создаётся путём вызова класса Tk. Для отображения графического интерфейса и взаимодействия с ним из окна необходимо вызвать метод mainloop. Вызвав метод mainloop, получим пустое окно под названием tk. Закроем его и создадим новое.
На этот раз дадим окну новое название и изменим его стандартные размеры. Название окна передаётся методу title, а размеры — методу geometry. Последний метод принимает строку, в которой через строчную букву x указываются ширина и высота окна в пикселях. Теперь при вызове метода mainloop отобразится окно 600x400 пикселей под названием Application.
Обратите внимание, что окно появилось не в центре экрана. По умолчанию окна отображаются ближе к левому верхнему углу экрана. Проблема решается путём передачи методу geometry отступов. Отступы указываются после размеров окна через знак сложения. Первый отступ задаёт расстояние в пикселях между левыми границами экрана и окна, а второй — между верхними границами экрана и окна. Если правильно рассчитать отступы, то окно будет отображено в центре экрана.
Отступ по горизонтали рассчитывается следующим образом. Метод winfo_screenwidth возвращает ширину экрана в пикселях. Если разделить этот размер на 2, а затем вычесть половину ширины окна, то получим искомый отступ по горизонтали. Единственное, его ещё следует преобразовать в целое число. Аналогичный расчёт проводится для отступа по вертикали. Найденные отступы и размеры окна можно добавить в целевую строку методом format.
Виджет окно — это контейнер, в который помещаются другие виджеты. Одним из таких является виджет Label или метка. Чтобы создать метку, следует вызвать класс Label. Классы, создающие виджеты, принимают множество именованных аргументов для настройки их внешнего вида. В этом примере классу Label передаётся шесть именованных аргументов.
Аргумент text добавляет в метку текст. Аргументом font настраивается шрифт и размер добавляемого в метку текста. Следующие аргументы bg и fg устанавливают цвет метки и текста. И последними двумя аргументами настраивается ширина и высота метки. Здесь важно отметить, что размеры метки указываются не в пикселях, а в текстовых юнитах.
Горизонтальный текстовый юнит определён шириной символа “0”. То есть метка шириной 10 уместит строку, состоящую из десяти нулей. Аналогичным образом вертикальный текстовый юнит определён высотой символа “0”. Метка высотой 5 уместит 5 строк текста. После создания виджета его необходимо добавить в окно. Данную задачу выполняют менеджеры геометрии.
В этом уроке мы рассмотрим только один менеджер геометрии, которым является метод pack. Вызов этого метода без аргументов добавит виджет в верхнюю часть окна ровно по центру. Похожим на метку виджетом является Button или кнопка. Кнопка — это, по сути, метка, на которую можно нажимать. Кнопку создаёт класс Button.
В этом примере классу передаются те же аргументы, что и при создании метки. Также классу передаётся новый аргумент command. Значением этого аргумента должна быть ссылка на функцию, которую следует вызвать при нажатии на кнопку. В данном случае будет вызываться функция add_label. Эта функция создаёт метку и за счёт вызова метода pack добавляет её в окно.
Запустим программу и посмотрим, что произойдёт. Как видите, отобразилось окно с одной кнопкой. Если нажать на кнопку, в окно добавится метка. Следует заметить, что метод pack для добавления виджета использует незанятое пространство окна. Поэтому при нажатии на кнопку метка добавилась ровно под кнопкой.
Следующий виджет называется Entry или однострочное текстовое поле. Это небольшой текстовый бокс, в который можно вводить текст. Однострочное текстовое поле создаётся путём вызова класса Entry. В этом примере классу передаётся ширина виджета, а также шрифт и размер вводимого текста. Введённый текст можно получить методом get.
В данном случае строка, которую вернёт метод get, используется в качестве названия метки. Кроме того, текстовое поле можно очистить от текста методом delete. Метод принимает индексы символов, в диапазоне которых должно произойти удаление текста. Здесь методу передаётся индекс первого символа и константа END пакета tkinter, что означает удаление всего текста из виджета.
Запустим эту программу. При запуске программы отобразилось окно с однострочным текстовым полем и кнопкой. Введём в текстовое поле слово Label и нажмём на кнопку. Как видите, это привело к тому, что в окно добавилась метка с введённым текстом. Кроме того, после нажатия кнопки текстовое поле было очищено.
Помимо однострочных текстовых полей, tkinter позволяет создавать многострочные текстовые поля. Для создания такого виджета используется класс Text. В отличие от класса Entry, классу Text можно передать высоту виджета. То есть отображаемое количество строк текстового поля. Виджеты текстовых полей можно использовать не только для ввода текста, но и для вывода.
В последнем случае используется метод insert. Если этому методу первым аргументом передать константу END, а вторым аргументом некоторую строку, то указанная строка вставится в конец текста текстового поля. В данном случае вставляемый в поле текст — это строковое представление текущего времени. Таким образом, при каждом нажатии кнопки в текстовое поле будет вставляться текущее время. Причём актуальное время будет вставляться в конец текста.
Теперь подробнее рассмотрим менеджер геометрии pack, который отвечает за добавление виджетов в окно. По умолчанию pack добавляет виджеты в верхнюю часть незанятого пространства окна по центру. При этом данный метод принимает именованные аргументы, с помощью которых можно управлять расположением виджетов. Аргумент side указывает методу pack, у какой границы окна разместить виджет.
Значением этого аргумента может быть одна из четырёх констант пакета tkinter: TOP, BOTTOM, LEFT или RIGHT. К примеру, если методу pack передать аргумент side со значением BOTTOM, виджет будет размещён у нижней границы окна по центру. Ещё один аргумент, настраивающий расположение виджета в окне, называется anchor. Значением аргумента может быть одна из следующих констант.
Например, если методу pack передать константу SW, означающую юго-запад, то в сочетании с константой BOTTOM виджет добавится в левый нижний угол окна. Кроме того, метод pack принимает аргумент fill, который позволяет растягивать виджеты в окне. Значением аргумента может быть одна из трёх констант: X, Y или BOTH, означающие, соответственно, растяжение виджета по горизонтали, по вертикали или в обе стороны.
В этом примере первая метка растягивается по горизонтали, а вторая — по вертикали. Также метод pack принимает аргумент expand с логическим значением. Если значением аргумента будет True, то это разрешит менеджеру геометрии растянуть виджет в обе стороны. При этом значением аргумента fill должна быть константа BOTH. Как результат, получим виджеты, заполняющие всё пространство окна.
Последний виджет, который мы разберём в данном уроке — это меню. Меню можно охарактеризовать как набор команд или дополнительных подменю с командами в верхней части графического интерфейса программы. Виджет меню создаётся путём вызова класса Menu. Для добавления меню в окно менеджеры геометрии не используются.
Вместо этого ссылку на экземпляр класса Menu необходимо передать методу config, который вызывается из окна. Так создаётся главное меню, которое в дальнейшем можно наполнить командами или, как делают чаще, подменю с командами. В этом примере в главное меню добавляется подменю из двух команд. Это реализовано следующим образом.
В первую очередь создаётся ещё один экземпляр класса Menu. Однако на этот раз классу передаётся ссылка на родительский виджет. То есть виджет, в котором будет размещено подменю. Помимо этого классу передаётся аргумент tearoff, запрещающий откреплять виджет. Далее в подменю методом add_command добавляются две команды: методу передаются названия команд и lambda выражения.
Напомню, что lambda выражение интерпретируется как ссылка на lambda функцию. В данном случае такой приём позволит вызывать функцию add_label с аргументом. И, наконец, методом add_cascade, который вызывается из родительского виджета, подменю добавляется в главное меню. Для этого методу переда