
После написания программы ее можно модифицировать и добавить графический интерфейс — с 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-документ и добавить в него разметку.
<head>
<meta charset="UTF-8">
<!-- добавляем название окна программы -->
<title>T-Rex</title>
<script src="eel.js"></script>
</head>
<body>
<!-- выводим текст -->
<h1>Hello, T-Rex!</h1>
</body>
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 на тачбаре.
Полезные материалы для разработчиков



Комментарии (54)
Jenyay
25.07.2023 12:52+6А как же wxPython?
Doctor_IT Автор
25.07.2023 12:52+1Добрый день!
Я писал про инструменты, с которыми работал N-ое количество времени)
Расскажите, в каких задачах wxPython используете вы? В чем его особенности?
Jenyay
25.07.2023 12:52+3Надеюсь, не сочтут за рекламу, но самый крупный проект, который я делал (делаю) на wxPython - это программа для хранения заметок (https://jenyay.net/Soft/Outwiker). Мне в wxPython нравится, что есть встроенный веб-компонент, который под Windows использует IE или Edge, а под Linux - WebKit. Еще wxPython хорошо интегрируется с графиками из Matplotlib, если надо сделать какой-нибудь интерфейс к расчету с графиками.
saltpepper
25.07.2023 12:52Мне полюбился PyQtGraph для интерфейсов в научном софте, работает шустро и есть готовые хорошие компоненты с визуализацией графиков и интерактивностью. Но чтобы что-то свое написать приходится в кишках поковыряться, это да. Работает и с PySide и PyQt.
brake
25.07.2023 12:52Вроде там нативные элементы управления используются под каждой ОС. Поэтому программа выглядит нативно, а не замаскирована под нативную. Если не ошибаюсь.
Писал на нём прогу с несколькими формами - ничего плохого не могу сказать.
И да, wxFormBuilder мне очень в этом помог.
megamrmax
25.07.2023 12:52Удачно я зашел! Планирую запилить себе интерфейс для робота, который делает всякие сделки на фондовом рынке. Какую тулзу лучше использовать, чтобы можно было запускать на любой платформе и чтоб умела рисовать красивые графики....и можно было создать "приятный глазу интерфейс". Смотрю в сторону Kivy но может есть другие интересные варианты. Спасибо!
LaRos89098
25.07.2023 12:52+1Советую глянуть в сторону NiceGui. Не реклама, работаю с ним последние несколько месяцев. Позволяет достаточно быстро собрать красивый и функциональный интерфейс. Есть встроенная поддержка многих фреймворков для графиков.
JaimeLanister
25.07.2023 12:52>чтобы можно было запускать на любой платформе и чтоб умела рисовать красивые графики...
PySide2/6 + QML
rg_software
25.07.2023 12:52+2Важно или нет, но Qt поддерживает альтернативный байндинг PySide в качестве официального.
MyWave
25.07.2023 12:52Я писал на ткинтере полтора года назад ГУИ программку по работе. Вот часть функционала: https://github.com/Alexis-D-ff/python_duplicate_catalyst_gui (в этой версии только поиск дубликатов файлов реализован).
Не пользуйтесь им, он вас сожрёт. Лагучая древняя печка, с обрубленным функционалом. Три виджета с анимацией на экране = лаги.
Я бы на Qt писал но в 2022 для Python API не было документации.
А если задача позволяет, лучше веб приложение делать, а не это овно мамонта из 2002 (я про декстоп приложения).
cdriper
25.07.2023 12:52+5неужели нашелся хоть один живой человек, любитель электрона?
если кто и любит это извращение, так только те, кто это разрабатывает и получает за это зарплату
K_Chicago
25.07.2023 12:52вопрос насчет "веб приложения". Мне нужно сделать web-интерфейс к БД Postgres. Чтобы был data grid, со стандартным фаршем - сортировка, добавление кнопок в строку, реакция на клик в клетке таблицы, ну и плюс простенький програмный интерфейс - табы, поп-листы заселенные запросом, модальные окна. Я НЕ веб-программист, IDE должен быть бесплатным, поддерживаемым AWS.
И желательно с минимизацией кодирования, т.е. все это можно создать руками на JS, но мне нужно что-то вроде компонентов.Я перерыл как мог кучу фреймворков, все либо коммерческое, либо не работает с PG, либо с минимальным убогим набором компонентов.
В результате я остановился на редком звере- библиотека Shiny языка R. В общем удовлетворяет всем моим требованиям. Куча компонентов, в том числе кастомных, поддерживает соединение с PG, живет на AWS, dataGrid компоненты весьма продвинутые с минимумом кодирования. Ну, не без недостатков. Дурная логика программирования с реактивностью, нельзя сделать многостраничность, нет асинхронности, очень запутаный способ работы с модулями (когда программа разростается).
Вот пример как это выглядит (пардон, скрыл некоторые данные):
https://i.imgur.com/Z6Vye68.jpg
Все еще тешу себя надеждой - а может быть кто-то знает альтернативу?
Dosyk
25.07.2023 12:52была аналогичная задача, веб морда для постргрес, похожая на твою, сделал на фласке, все тоже не сложно и я не веб программист)
HemulGM
25.07.2023 12:52Вероятно вы мало знаете о фреймворках для десктопа и их возможностях.
Для примера: https://github.com/HemulGM/ChatGPT
HemulGM
25.07.2023 12:52- А может не писать на питоне GUI и использовать компилируемые нативно языки для создания быстрого и эффективного интерфейса?
- Да не, бред какой-тоDoctor_IT Автор
25.07.2023 12:52Очевидно, что не каждому проекту нужен интерфейс, который будет потреблять на пару десятков меньше мегабайт ОЗУ) Все зависит от задачи: прочитайте статью — я описал конкретные юзкейсы, когда оптимальней было писать GUI на Python.
И что вы подразумеваете под «нативно компилируемые языки» — неужели от способа исполнения байт-кода всегда сильно зависит быстродействие и потребление памяти? Это не так: например, PyQt транскрибирует все в стандартный движок Qt, как и C++. Документация, объекты, сам движок — все идентично)
То же самое касаемо OpenGL. Неужели написанная 3D-сцена на PyOpenGL будет сильно проигрывать версии на C++?
HemulGM
25.07.2023 12:52-3Когда твой интерфейс статичен - конечно нет. Конечно все будет одинаково работать. Однако, как только питон начнет управлять этим интерфейсом в реальном времени, тогда и будет заметно проигрывать.
Обновление таблиц, графиков, текстового содержимого и т.д. Все это будет работает намного медленнее, чем с нативным языком.
В том числе и с OpenGL. Рисуется же не средствами питона, а самим движком. Однако, если будет много объектов, то построении кадра будет сильно страдать. Пока он переберет все объекты, пока отправит команду на передачу инструкции движку. Все это будет очень медленно.
DrMefistO
25.07.2023 12:52Какие нативно компилируемые языки имеют удобную возможность создавать GUI не вникая в чуть ли не в язык в языке типа Qt (если пишешь на сях)?
Я только о imGui знаю. И то, его подключить - это целая проблема.
rg_software
25.07.2023 12:52+1Когда пишу на C++, использую wxWidgets. Он в целом куда легковеснее Qt и без каких-либо кодогенераторов и проч.
JaimeLanister
25.07.2023 12:52-1Хороший GUI от логики приложения отеделен и уже скомпилирован.
По работе использую один и тот же интерфейс на QML из питона и C++ и разницы в отзывчивости нет вообще никакой.
Chupakabra303
25.07.2023 12:52+1А как же Dear PyGui?
abagnale
25.07.2023 12:52+1Странно, за что минусы ставят за Dear PyGui? Я бы тоже его назвал.
Кто может, те конечно возьмут оригинальный Dear ImGui и будут писать на C++, но статья задала Python.
atshaman
25.07.2023 12:52Если не изменяет память - то в свое время в komodo ide был работающий (!) gui builder для tk(inter). В последние лет уже... много обхожусь либо cli, либо webней - но тут кому какие задачи решать.
saipr
25.07.2023 12:52+2Вы можете использовать сетки grid и менеджеры геометрии place и pack. Наверное, изучение этих инструментов — самый тяжелый этап при погружении в Tkinter. Особенно, если вы хотите научиться делать адаптивные интерфейсы.
На самом деле не так страшен черт как его малюют. Первое что надо помнить, что pack и grid нельзя использовать одновременно на одном виджете. А вот place позволяет размещать виджеты где угодно. Что касается pack и grid то освоив с десяток правил можно создавать адаптивные интерфейсы без проблем.
ainoneko
25.07.2023 12:52Пробовал как-то раз недавно использовать PyQt: не заработало даже меньшее, чем hello-world: уже "app = QApplication(sys.argv)" выдаёт:
"qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in ““ even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland‑egl, wayland, wayland‑xcomposite‑egl, wayland‑xcomposite‑glx, webgl, xcb.
Aborted”
Гугление (мне) выдаёт рекомендации типа "переустановите ту часть программы, что вы подключаете к QT".
В результате решил попробовать Kivy, которое пока работает.
+: В пет-проекте использовал Tkinter, тоже всё работало (только в плагине оказался баг, который пришлось исправить (но мой пулл-реквест до сих пор не принят)).
JaimeLanister
25.07.2023 12:52PySide + QML:
Декларативное описание интерфейса: один раз попробуешь, на меньшее согласен не будешь.
Разделение логики и интерфейса, возможность переиспользовать интерфейс из С++.
Относительно легко можно делать очень продвинутый или нестандартный интерфейс.
HemulGM
25.07.2023 12:52Какое "Разделение логики и интерфейса", если вы в том же коде прописываете то, как элементы управления работают? Заполняете их и навешиваете события (реакции).
JaimeLanister
25.07.2023 12:52Интерфейс в .qml/.js и он ничего не знает о потрохах, все сложное - в .py/.cpp.
HemulGM
25.07.2023 12:52С контролами вы как общаетесь в .py/.cpp? Напрямую обращение к контролам или через отдельный контроллер? События где и когда навешиваются?
JaimeLanister
25.07.2023 12:52Через свойства и сигналы и слоты. Если рашьне не работали с Qt, то это, наверное, мало что говорит.
Представьте, что в py/cpp есть объект customer, у него есть свойство name. В декларативоном GUI на QML можно написать примерно так:Text {
text: "Имя пользователя: " + customer.name
}
Все. Это создаст визуальный элемент отображащий имя пользователя и обновляющий его при необходимости. Явно обрабатывать изменение имени в py/cpp не надо. Можно сделать связь и в другую сторону, когда значение поля меняется в GUI и автоматически обновляется в py/cpp. И да, все это работает на практически любых платфомах и работает быстро.HemulGM
25.07.2023 12:52Я работал с Qt и знаю про слоты и сигналы.
Однако, вот вы же напрямую указали поле объекта в коде QML. Это и есть прямая связь между кодом и интерфейсом.
QML знает о данных из cpp/py и напрямую может воздействовать на логику.
Разделение логики и интерфейса, это когда есть посредник, который разделяет логику и интерфейс. В вашем примере его просто нет.
saipr
25.07.2023 12:52+1Кстати, представленный ниже GUI написан на TK, значит может быть представлен и на Tkinter:
JaimeLanister
25.07.2023 12:52Дизайн из 1995-го года.
saipr
25.07.2023 12:52Дизайн может и несёт на себе отпечаток 1995 года, но GUI написано с использованием SVG-графике\и, поддержка которой в tk появилась в 2006 году. Поддержка появилась в виде пакета tkpath, автором которого был Матс Бенгтссон (Mats Bengtsson):
EgorBakulin
25.07.2023 12:52По поводу Eel не очень наглядно. Было бы здорово, в примере, подкинуть в разметку текст из питоновского файла
CrinitusFeles
25.07.2023 12:52можно обратить внимание на flet https://flet.dev, хоть от питона там только обертка
killla
25.07.2023 12:52Для типичных задач, с которыми можно столкнуться на питоне (что-то одноразовое / простое / демонстрационное / учебное / сбоку от основного проекта), PySimpleGUI справляется. Он может работать и на базе Tk, и на базе QT, и на базе Wx, и теоретически можно через web пробросить интерфейс. Это вроде самая популярная библиотека для GUI на питоне, странно, что её нет в статье.
Для серьезного есть смысл посмотреть на tauri - более шустрый аналог electron.
ivankudryavtsev
Мы используем Kivy и PySimpleGUI.
Doctor_IT Автор
Расскажите, пожалуйста, подробнее про PySimpleGUI. Если честно, впервые о нем слышу. Как он помогает решать вашу задачу? Ведь не просто так вы используете два инструмента для интерфейса ????
LaRos89098
Тут ответ кроется в названии) Simple - простой. Эта библиотека действительно очень простая и позволяет быстро собрать простой GUI. Я например использую её для небольших скриптов, а под средние задачи использую NiceGUI, тоже очень интересное решение, основанное на веб-интерфейсе
ivankudryavtsev
У нас довольно простой UI, ориентированный на AI видео-аналитику. Мы выбирали по принципу, что Nuitka может скомпилировать UI в бинарник.
Levitanus
+100500, два равноценно отличных пакета под разные задачи. QT на Python ‒ страшный сон.