Как сделать код python gui
Перейти к содержимому

Как сделать код python gui

  • автор:

Четыре способа написать Hello world, или инструменты для создания GUI на Python

После написания программы ее можно модифицировать и добавить графический интерфейс — с Python это проще, чем кажется. Для программирования красивого и функционального GUI иногда достаточно простого знания html и css.

Под катом — подборка некоторых инструментов для создания интерфейсов на Python. Сохраняйте статью в закладки и предлагайте свои варианты в комментариях!

Привет! Меня зовут Влад и уже более пяти лет я пишу на Python. Успел перепробовать многое — от олимпиадного программирования и решения исследовательских задач до BackEnd-разработки и RPA.

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

Если вам интересен такой формат, напишите, какую тему можно разобрать в будущем. За самую интересную идею отправим плюшевого тирекса и другой мерч Selectel.

Tkinter

Наверное, каждый заклинатель змей пробовал работать с Tkinter. Для меня это была одна из тех библиотек, с которой началось знакомство с возможностями Python.

Tkinter — это один из самых известных модулей для программирования интерфейсов под Windows, Linux и Mac.

Преимущества модуля:

  • Простая установка. Достаточно установить модуль и импортировать его в программу.
  • Интуитивная логика. Все просто: вызываете объект, создаете и добавляете графические элементы.

Когда-то давно я писал программу для «местных бухгалтеров», которая сравнивала электронные таблицы. Нужно было сделать интерфейс, чтобы заказчики могли работать с программой самостоятельно. И для этой задачи Tkinter хватило с запасом.

С помощью этого модуля можно делать простые десктопные приложения. Исходя из моего опыта, Tkinter отлично подходит для начинающих исследователей, которым наскучил софт вроде LabVIEW и хочется написать свой интерфейс для расчетов.

Пример работы

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

# импортируем модуль from tkinter import * def hello_world(): print("Hello world") # создаем окно main main = Tk() # добавляем кнопку, настраиваем ее форму и цвет # при нажатии сработает функция hello world btn = Button(main, width=20, height=7, text="Кнопка", bg="white", fg="black", command=hello_world) btn.pack() main.mainloop() 

Пример работы программы на Tkinter, простая кнопка.

Что нужно учитывать

Tkinter — это одновременно простой и сложный инструмент для создания GUI. Так, при построении «масштабных» интерфейсов возникают трудности: работать можно только с кодом, а механика размещения элементов не всегда очевидна.

Вы можете использовать сетки grid и менеджеры геометрии place и pack. Наверное, изучение этих инструментов — самый тяжелый этап при погружении в Tkinter. Особенно, если вы хотите научиться делать адаптивные интерфейсы.

Способы размещения элементов в Tkinter.

Eel

Знаете html и css — воспользуйтесь модулем Eel. С помощью него можно создавать веб-интерфейсы в виде отдельных программ. Яркий пример, который написан на Electron, прародителе Eel, — Discord.

С помощью библиотеки Eel можно не только написать красивый интерфейс на html и css, но и динамические анимации на базе JavaScript.

Пример работы

Шаг 1. Сначала нужно создать html-документ и добавить в него разметку.

   T-Rex   

Hello, T-Rex!

project/main.html

Шаг 2. Далее необходимо запустить html-документ с помощью Eel.

import eel eel.init("") eel.start("main.html", size=(700, 700)) 

project/start.py

Готово — после запуска программа откроет в браузере html-документ project/main.html:

Что нужно учитывать

Модуль создает GUI на базе ядра Chromium. Плохо это для вашего проекта или нет — знаете только вы. Но потенциально могут быть проблемы с оптимизацией, потреблением оперативной памяти.

Однако с помощью Eel можно выиграть в гибкости и упростить разработку сложных адаптивных приложений — достаточно использовать старый-добрый flexbox. Например, если вам нужно приложение для просмотра больших таблиц, на базе Eel можно просто создать GUI с html-фреймом Google Sheets.

При этом пользователь приложения как бы выполняет роль клиента и сервера одновременно. Eel запускает localhost:8000 и открывает браузер — Chrome или Windows Edge — с флагом —app , который позволяет задавать размер окна по умолчанию. Проект можно скомпилировать с помощью PyInstaller или Auto PY to EXE и распространять как исполняемый файл.

Интересен Python? Мы собрали самые интересные и популярные запросы разработчиков в одном файле! По ссылке — материалы по геймдеву, машинному обучению, программированию микроконтроллеров и графических интерфейсов.

PyQt

До сих пор мы рассматривали модули, на базе которых можно именно написать интерфейс. Но есть более удобный (имхо) и профессиональный инструмент для создания GUI — библиотека PyQt. Ее преимущество — совместимость с билдером Qt Designer, который предоставляет набор готовых интерфейсных элементов.

Qt Designer, интерфейс редактора.

Пример работы

Для создания интерфейса достаточно установить PyQt через пакетный менеджер pip, набросать интерфейс в QtDesigner, сохранить его в формате .ui и подключить к программе.

Посмотрим на примере, как написать простой интерфейс и обрабатывать нажатия кнопки (pushButton):

# подключаем необходимые пакеты from PyQt6 import uic from PyQt6.Widgets import QApplications # эта функция срабатывает при нажатии кнопки def hello_world(): print("Hello world") # подключаем файл, полученный в QtDesigner Form, Window = uic.loaduiType("interface.ui") app = QApplication([]) window, form = Window(), Form() form.setupUi(window) window.show() # настраиваем сценарий для элемента pushButton form.pushButton.clicked.connect(hello_world) # запускаем окно программы app.exec() 

После запуска и клика по кнопке программа напечатает Hello world — проверьте это самостоятельно. Но настоящие преимущества PyQt раскрываются во время разработки сложных интерфейсов.

В своей практике я использовал PyQt для кроссплатформенных GUI под задачи по автоматизации. Яркий пример — конвертер статей из Google-документов на Хабр, о котором я рассказывал в предыдущей статье.

Что нужно учитывать

Встроенных элементов Qt почти всегда было достаточно. Однако иногда могут встречаться объекты, которые некорректно срабатывают. Например — QTextBrowser, который не умеет считывать сложный html-код вроде blockquote.

Главное преимущество PyQt — подробная документация, в которой хорошо описаны все интерфейсные элементы, их параметры и типы данных. Поверьте, для работы с этим фреймворком справочные материалы понадобятся не раз. Но если вам ближе видеоформат, могу смело порекомендовать уроки Олега Шпагина.

PyTouchBar

С 2016 года у некоторых моделей MacBook Pro есть сенсорная OLED-панель. По сути, она просто заменяет функциональные клавиши. Но с ней чуть интересней: на тачбар можно вывести закладки и даже медиаэлементы.

С помощью библиотеки PyTouchBar можно сделать свой интерфейс для тачбара и даже создать игру — без погружения в дебри драйверов и разработки на Swift. О том, как это сделать, мы подробно рассказали в отдельной статье.

Игра с динозавриком Google на тачбаре.

Python GUI: создаём простое приложение с PyQt и Qt Designer

Помимо всего прочего, на Python можно создавать десктопные приложения с графическим интерфейсом (Python GUI). Это можно сделать с помощью PyQt и Qt Designer, с которыми мы сегодня познакомимся.

Обложка поста Python GUI: создаём простое приложение с PyQt и Qt Designer

Эта статья предназначена для тех, кто только начинает своё знакомство с созданием приложений с графическим интерфейсом (GUI) на Python. В ней мы рассмотрим основы использования PyQt в связке с Qt Designer. Шаг за шагом мы создадим простое Python GUI приложение, которое будет отображать содержимое выбранной директории.

Что нам потребуется

Нам понадобятся PyQt и Qt Designer, ну и Python, само собой.

В этой статье используется PyQt5 с Python 3, но особых различий между PyQt и PySide или их версиями для Python 2 нет.

Windows: PyQt можно скачать здесь. В комплекте с ним идёт Qt Designer.

macOS: Вы можете установить PyQt с помощью Homebrew:

$ brew install pyqt5

Скачать пакет с большинством компонентов и инструментов Qt, который содержит Qt Designer, можно по этой ссылке.

Linux: Всё нужное, вероятно, есть в репозиториях вашего дистрибутива. Qt Designer можно установить из Центра Приложений, но PyQt придётся устанавливать через терминал. Установить всё, что нам понадобится, одной командой можно, например, так:

# для Fedora: $ sudo dnf install python3-qt5 qt-creator # для Debian/Ubuntu: $ sudo apt install python3-qt5 pyqt5-dev-tools qtcreator 

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

$ pyuic5 Error: one input ui-file must be specified 

Если вы видите сообщение, что такой команды нет или что-то в таком роде, попробуйте загуглить решение проблемы для вашей операционной системы и версии PyQt.

Если вы используете Windows, то, скорее всего, путь C:\Python36\Scripts (измените 36 на вашу версию Python) не прописан в вашем PATH . Загляните в этот тред на Stack Overflow, чтобы узнать, как решить проблему.

Дизайн

Основы

Теперь, когда у нас всё готово к работе, давайте начнём с простого дизайна.

Откройте Qt Designer, где вы увидите диалог новой формы, выберите Main Window и нажмите Create.

Python GUI: создаём простое приложение с PyQt и Qt Designer 1

После этого у вас должна появиться форма — шаблон для окна, размер которого можно менять и куда можно вставлять объекты из окна виджетов и т.д. Ознакомьтесь с интерфейсом, он довольно простой.

Теперь давайте немного изменим размер нашего главного окна, т.к. нам не нужно, чтобы оно было таким большим. А ещё давайте уберём автоматически добавленное меню и строку состояния, поскольку в нашем приложении они не пригодятся.

Все элементы формы и их иерархия по умолчанию отображаются в правой части окна Qt Designer под названием Object Inspector. Вы с лёгкостью можете удалять объекты, кликая по ним правой кнопкой мыши в этом окне. Или же вы можете выбрать их в основной форме и нажать клавишу DEL на клавиатуре.

Python GUI: создаём простое приложение с PyQt и Qt Designer 2

В итоге мы имеем почти пустую форму. Единственный оставшийся объект — centralwidget , но он нам понадобится, поэтому с ним мы ничего не будем делать.

Теперь перетащите куда-нибудь в основную форму List Widget (не List View) и Push Button из Widget Box.

Макеты

Вместо использования фиксированных позиций и размеров элементов в приложении лучше использовать макеты. Фиксированные позиции и размеры у вас будут выглядеть хорошо (пока вы не измените размер окна), но вы никогда не можете быть уверены, что всё будет точно так же на других машинах и/или операционных системах.

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

Давайте создадим нашу первую форму без использования макетов. Перетащите список и кнопку в форме и измените их размер, чтобы вышло вот так:

Python GUI: создаём простое приложение с PyQt и Qt Designer 3

Теперь в меню Qt Designer нажмите Form, затем выберите Preview и увидите что-то похожее на скриншот выше. Выглядит хорошо, не так ли? Но вот что случится, когда мы изменим размер окна:

Python GUI: создаём простое приложение с PyQt и Qt Designer 4

Наши объекты остались на тех же местах и сохранили свои размеры, несмотря на то что размер основного окна изменился и кнопку почти не видно. Вот поэтому в большинстве случаев стоит использовать макеты. Конечно, бывают случаи, когда вам, например, нужна фиксированная или минимальная/максимальная ширина объекта. Но вообще при разработке приложения лучше использовать макеты.

Основное окно уже поддерживает макеты, поэтому нам ничего не нужно добавлять в нашу форму. Просто кликните правой кнопкой мыши по Main Window в Object Inspector и выберите Lay outLay out vertically. Также вы можете кликнуть правой кнопкой по пустой области в форме и выбрать те же опции:

Python GUI: создаём простое приложение с PyQt и Qt Designer 5

Ваши элементы должны быть в том же порядке, что и до внесённых изменений, но если это не так, то просто перетащите их на нужное место.

Так как мы использовали вертикальное размещение, все элементы, которые мы добавим, будут располагаться вертикально. Можно комбинировать размещения для получения желаемого результата. Например, горизонтальное размещение двух кнопок в вертикальном будет выглядеть так:

Python GUI: создаём простое приложение с PyQt и Qt Designer 6

Если у вас не получается переместить элемент в главном окне, вы можете сделать это в окне Object Inspector.

Последние штрихи

Теперь, благодаря вертикальному размещению, наши элементы выровнены правильно. Единственное, что осталось сделать (но не обязательно), — изменить имя элементов и их текст.

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

Свойства элементов можно изменить в разделе Property Editor.

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

Нажмите на кнопку, которую вы добавили в форму. Теперь в Property Editor вы должны видеть все свойства этого элемента. В данный момент нас интересуют objectName и text в разделе QAbstractButton . Вы можете сворачивать разделы в Property Editor нажатием по названию раздела.

Измените значение objectName на btnBrowse и text на Выберите папку.

Должно получиться так:

Python GUI: создаём простое приложение с PyQt и Qt Designer 7

Именем объекта списка является listWidget , что вполне подходит в данном случае.

Сохраните дизайн как design.ui в папке проекта.

Превращаем дизайн в код

Конечно, можно использовать .ui -файлы напрямую из Python-кода, однако есть и другой путь, который может показаться легче. Можно конвертировать код .ui -файла в Python-файл, который мы потом сможем импортировать и использовать. Для этого мы используем команду pyuic5 из терминала/командной строки.

Чтобы конвертировать .ui -файл в Python-файл с названием design.py , используйте следующую команду:

$ pyuic5 path/to/design.ui -o output/path/to/design.py 

Пишем код

Теперь у нас есть файл design.py с нужной частью дизайна нашего приложения и мы начинать работу над созданием его логики.

Создайте файл main.py в папке, где находится design.py .

Используем дизайн

Для Python GUI приложения понадобятся следующие модули:

import sys # sys нужен для передачи argv в QApplication from PyQt5 import QtWidgets 

Также нам нужен код дизайна, который мы создали ранее, поэтому его мы тоже импортируем:

import design # Это наш конвертированный файл дизайна 

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

class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow): def __init__(self): # Это здесь нужно для доступа к переменным, методам # и т.д. в файле design.py super().__init__() self.setupUi(self) # Это нужно для инициализации нашего дизайна 

В этом классе мы будем взаимодействовать с элементами интерфейса, добавлять соединения и всё остальное, что нам потребуется. Но для начала нам нужно инициализировать класс при запуске кода. С этим мы разберёмся в функции main() :

def main(): app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication window = ExampleApp() # Создаём объект класса ExampleApp window.show() # Показываем окно app.exec_() # и запускаем приложение 

И чтобы выполнить эту функцию, мы воспользуемся привычной конструкцией:

if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем main() # то запускаем функцию main() 

В итоге main.py выглядит таким образом:

import sys # sys нужен для передачи argv в QApplication from PyQt5 import QtWidgets import design # Это наш конвертированный файл дизайна class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow): def __init__(self): # Это здесь нужно для доступа к переменным, методам # и т.д. в файле design.py super().__init__() self.setupUi(self) # Это нужно для инициализации нашего дизайна def main(): app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication window = ExampleApp() # Создаём объект класса ExampleApp window.show() # Показываем окно app.exec_() # и запускаем приложение if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем main() # то запускаем функцию main() 

Если запустить этот код: $ python3 main.py , то наше приложение запустится!

Python GUI: создаём простое приложение с PyQt и Qt Designer 8

Но нажатие на кнопку ничего не даёт, поэтому нам придётся с этим разобраться.

Добавляем функциональность в наше Python GUI приложение

Примечание Весь дальнейший код пишется внутри класса ExampleApp .

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

self.btnBrowse.clicked.connect(self.browse_folder) 

Добавьте эту строку в метод __init__ класса ExampleApp , чтобы выполнить привязку при запуске приложения. А теперь взглянем на неё поближе:

  • self.btnBrowse : здесь btnBrowse — имя объекта, который мы определили в Qt Designer. self говорит само за себя и означает принадлежность к текущему классу;
  • clicked — событие, которое мы хотим привязать. У разных элементов разные события, например, у виджетов списка есть itemSelectionChanged и т.д.;
  • connect() — метод, который привязывает событие к вызову переданной функции;
  • self.browse_folder — просто функция (метод), которую мы описали в классе ExampleApp .

Для открытия диалога выбора папки мы можем использовать встроенный метод QtWidgets.QFileDialog.getExistingDirectory :

directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку") 

Если пользователь выберет директорию, переменной directory присвоится абсолютный путь к выбранной директории, в противном случае она будет равна None . Чтобы не выполнять код дальше, если пользователь закроет диалог, мы используем команду if directory: .

Для отображения содержимого директории нам нужно импортировать os :

import os 

И получить список содержимого следующим образом:

os.listdir(path) 

Для добавления элементов в listWidget мы используем метод addItem() , а для удаления всех элементов у нас есть self.listWidget.clear() .

В итоге функция browse_folder должна выглядеть так:

def browse_folder(self): self.listWidget.clear() # На случай, если в списке уже есть элементы directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку") # открыть диалог выбора директории и установить значение переменной # равной пути к выбранной директории if directory: # не продолжать выполнение, если пользователь не выбрал директорию for file_name in os.listdir(directory): # для каждого файла в директории self.listWidget.addItem(file_name) # добавить файл в listWidget 

Теперь, если запустить приложение, нажать на кнопку и выбрать директорию, мы увидим:

Python GUI: создаём простое приложение с PyQt и Qt Designer 9

Так выглядит весь код нашего Python GUI приложения:

import sys # sys нужен для передачи argv в QApplication import os # Отсюда нам понадобятся методы для отображения содержимого директорий from PyQt5 import QtWidgets import design # Это наш конвертированный файл дизайна class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow): def __init__(self): # Это здесь нужно для доступа к переменным, методам # и т.д. в файле design.py super().__init__() self.setupUi(self) # Это нужно для инициализации нашего дизайна self.btnBrowse.clicked.connect(self.browse_folder) # Выполнить функцию browse_folder # при нажатии кнопки def browse_folder(self): self.listWidget.clear() # На случай, если в списке уже есть элементы directory = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку") # открыть диалог выбора директории и установить значение переменной # равной пути к выбранной директории if directory: # не продолжать выполнение, если пользователь не выбрал директорию for file_name in os.listdir(directory): # для каждого файла в директории self.listWidget.addItem(file_name) # добавить файл в listWidget def main(): app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication window = ExampleApp() # Создаём объект класса ExampleApp window.show() # Показываем окно app.exec_() # и запускаем приложение if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем main() # то запускаем функцию main() 

На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.

Это были основы использования Qt Designer и PyQt для разработки Python GUI приложения. Теперь вы можете спокойно изменять дизайн приложения и использовать команду pyuic5 без страха потерять написанный код.

Как создать GUI-приложение на Python

Изучите создание простых и мощных GUI-приложений на Python с помощью Tkinter и PyQt, двух популярных библиотек, в этой информативной статье для новичков.

Python programming for GUI development.

Алексей Кодов
Автор статьи
23 июня 2023 в 18:53

Создание графического пользовательского интерфейса (GUI) для приложения на Python может быть выполнено с помощью различных библиотек. В этой статье мы рассмотрим две популярные библиотеки: Tkinter и PyQt.

Tkinter

Tkinter — это стандартная библиотека Python для создания легких и простых GUI-приложений. Она является одной из самых быстрых и простых в использовании библиотек для создания графического интерфейса на Python.

Установка

Tkinter уже включена в стандартную библиотеку Python, поэтому вам не нужно устанавливать ее отдельно.

Пример использования Tkinter

import tkinter as tk def on_button_click(): print("Hello, Tkinter!") app = tk.Tk() app.title("My Tkinter App") button = tk.Button(app, text="Click me!", command=on_button_click) button.pack() app.mainloop()

В данном примере мы создаем базовое окно с кнопкой. При нажатии на кнопку в консоли выводится сообщение «Hello, Tkinter!».

PyQt

PyQt — это набор библиотек для создания настольных приложений с графическим интерфейсом, использующих фреймворк Qt. PyQt предлагает более мощный и гибкий инструментарий для создания GUI-приложений по сравнению с Tkinter.

Установка

Для установки PyQt выполните следующую команду:

pip install PyQt5

Пример использования PyQt

from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow import sys def on_button_click(): print("Hello, PyQt!") app = QApplication(sys.argv) window = QMainWindow() window.setWindowTitle("My PyQt App") button = QPushButton("Click me!", window) button.clicked.connect(on_button_click) button.show() window.show() sys.exit(app.exec_())

В данном примере мы создаем базовое окно с кнопкой. При нажатии на кнопку в консоли выводится сообщение «Hello, PyQt!».

Python-разработчик: новая работа через 9 месяцев
Получится, даже если у вас нет опыта в IT

Вывод

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

Не забывайте о практике и экспериментах с различными библиотеками, чтобы найти подходящий для вас инструмент для создания GUI-приложений на Python. Удачи вам в изучении и разработке! ��

Что такое Tkinter

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

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

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

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

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

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

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

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

Tkinter импортируется стандартно для модуля Python любым из способов:

  • import tkinter
  • from tkinter import *
  • import tkinter as tk

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

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

>>> from tkinter import * >>> TkVersion 8.6

Чтобы написать GUI-программу, надо выполнить приблизительно следующее:

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

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

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

root = Tk()

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

ent = Entry(root, width=20) but = Button(root, text="Преобразовать") lab = Label(root, width=20, bg='black', fg='white')

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

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

ent = Entry(width=20) but = Button(text="Преобразовать") lab = Label(width=20, bg='black', fg='white')

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

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

def str_to_sort_list(event): s = ent.get() s = s.split() s.sort() lab['text'] = ' '.join(s)

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

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

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

but.bind('', str_to_sort_list)

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

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

ent.pack() but.pack() lab.pack()

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

root.mainloop()

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

from tkinter import * def str_to_sort_list(event): s = ent.get() s = s.split() s.sort() lab['text'] = ' '.join(s) root = Tk() ent = Entry(width=20) but = Button(text="Преобразовать") lab = Label(width=20, bg='black', fg='white') but.bind('', str_to_sort_list) ent.pack() but.pack() lab.pack() root.mainloop() 

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

Пример программы на Python, написанной с помощью tkinter

Попробуем теперь реализовать в нашей программе объектно-ориентированный подход. Это необязательно, но позволяет связать/объединить вместе (вспомните про инкапсуляцию в ООП) виджет и функции, которые обрабатывают связанные с ним события, что концептуально более верно. В этом случае функции становятся методами.

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

from tkinter import * root = Tk() first_block = Block(root) root.mainloop()

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

class Block: def __init__(self, master): self.ent = Entry(master, width=20) self.but = Button(master, text="Преобразовать") self.lab = Label(master, width=20, bg='black', fg='white') self.but['command'] = self.str_to_sort self.ent.pack() self.but.pack() self.lab.pack() def str_to_sort(self): s = self.ent.get().split() s.sort() self.lab['text'] = ' '.join(s)

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

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

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

from tkinter import * class Block: def __init__(self, master, func): self.ent = Entry(master, width=20) self.but = Button(master, text="Преобразовать") self.lab = Label(master, width=20, bg='black', fg='white') # self.but['command'] = eval('self.' + func) self.but['command'] = getattr(self, func) self.ent.pack() self.but.pack() self.lab.pack() def str_to_sort(self): s = self.ent.get().split() s.sort() self.lab['text'] = ' '.join(s) def str_reverse(self): s = self.ent.get().split() s.reverse() self.lab['text'] = ' '.join(s) root = Tk() first_block = Block(root, 'str_to_sort') second_block = Block(root, 'str_reverse') root.mainloop() 

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

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

Окно с двумя блоками кнопки, метки и текстового поля

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

Практическая работа

Напишите простейший калькулятор, состоящий из двух текстовых полей, куда пользователь вводит числа, и четырех кнопок «+», «-«, «*», «/». Результат вычисления должен отображаться в метке. Если арифметическое действие выполнить невозможно (например, если были введены буквы, а не числа), то в метке должно появляться слово «ошибка».

Курс с примерами решений практических работ: pdf-версия

X Скрыть Наверх

Tkinter. Программирование GUI на Python

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *