десктоп приложение на python

Собираем проект на python3&PyQT5 под Windows, используя PyInstaller

Причиной написания статьи, явилось огромное количество постоянно возникающих у новичков вопросов такого содержания: «Как собрать проект c pyqt5», «Почему не работает», «Какой инструмент выбрать» и т.д. Сегодня научимся собирать проекты без мучений и танцев с бубном.

Как-то пришлось написать небольшое desktop-приложение. В качестве языка программирования для разработки был выбран python, поскольку для решения моей задачи он подходил идеально. В стандартную библиотеку Python уже входит библиотека tkinter, позволяющая создавать GUI. Но проблема tkinter в том, что данной библиотеке посвящено мало внимания, и найти в интернете курс, книгу или FAQ по ней довольно-таки сложно. Поэтому было решено использовать более мощную, современную и функциональную библиотеку Qt, которая имеет привязки к языку программирования python в виде библиотеки PyQT5. Более подробно про PyQT можете почитать здесь. В качестве примера я буду использовать код:

Существует большое количество библиотек, позволяющих это сделать, среди которых самые популярные: cx_Freeze, py2exe, nuitka, PyInstaller и др. Про каждую написано довольно много. Но надо сказать, что многие из этих решений позволяют запускать код только на компьютере, с предустановленным интерпретатором и pyqt5. Не думаю, что пользователь будет заморачиваться и ставить себе дополнительные пакеты и программы. Надеюсь, вы понимаете, что запуск программы на dev-среде и у пользователя это не одно и тоже. Также нужно отметить, что у каждого решения были свои проблемы: один не запускался, другой собирал то, что не смог потом запустить, третий вообще отказывался что-либо делать.

После долгих танцев с бубном и активным гуглением, мне все же удалось собрать проект с помощью pyinstaller, в полностью работоспособное приложение.

Немного о Pyinstaller

Pyinstaller собирает python-приложение и все зависимости в один пакет. Пользователь может запускать приложение без установки интерпретатора python или каких-либо модулей. Pyinstaller поддерживает python 2.7 и python 3.3+ и такие библиотеки как: numpy, PyQt, Django, wxPython и другие.

Pyinstaller тестировался на Windows, Mac OS X и Linux. Как бы там ни было, это не кросс-платформенный компилятор: чтобы сделать приложение под Windows, делай это на Windows; Чтобы сделать приложение под Linux, делай это на Linux и т.д.

PyInstaller успешно используется с AIX, Solaris и FreeBSD, но тестирование не проводилось.

Подробнее о PyInstaller можно почитать здесь: документация.

К тому же после сборки приложение весило всего около 15 мб. Это к слову и является преимуществом pyinstaller, поскольку он не собирает все подряд, а только необходимое. Аналогичные же библиотеки выдавали результат за 200-300 мб.

Приступаем к сборке

Прежде чем приступить к сборке мы должны установить необходимые библиотеки, а именно pywin32 и собственно pyinstaller:

Чтобы убедится, что все нормально установилось, вводим команду:

должна высветиться версия pyinstaller. Если все правильно установилось, идем дальше.

В папке с проектом запускаем cmd и набираем:

Собственно это и есть простейшая команда, которая соберет наш проект.
Синтаксис команды pyinstaller таков:

Наиболее часто используемые опции:

PyInstaller анализирует файл myscript.py и делает следующее:

В итоге наша команда будет выглядеть так:

После работы программы вы найдете две папки: dist и build. Собственно в папке dist и находится наше приложение. Впоследствии папку build можно спокойно удалить, она не влияет на работоспособность приложения.

Спасибо за внимание. Надеюсь статья была вам полезна.

Источник

Реальные примеры приложений на Python и PyQT: от косынки до веб-браузера

Авторизуйтесь

Реальные примеры приложений на Python и PyQT: от косынки до веб-браузера

десктоп приложение на python. python apps. десктоп приложение на python фото. десктоп приложение на python-python apps. картинка десктоп приложение на python. картинка python apps.

PyQt — набор «привязок» графического фреймворка Qt для языка программирования Python, выполненный в виде расширения Python. В нашей недавней статье мы рассмотрели создание простого приложения с использованием PyQt в связке с Qt Designer. Однако простым приложением функциональность PyQT не ограничивается. С его помощью можно создать приложения, начиная с привычного всем калькулятора и заканчивая веб-браузером. В этой статье мы рассмотрим 15 небольших десктопных приложений, написанных на Python с помощью PyQt. Приложения являются примерами использования разных частей фреймворка Qt, включая продвинутые виджеты, мультимедиа и другое. Исходники есть в этом репозитории на GitHub, так что спокойно скачивайте, изменяйте, экспериментируйте — в общем, делайте с ними всё, что душе угодно (в рамках лицензии MIT).

MooseAche

десктоп приложение на python. 1 1. десктоп приложение на python фото. десктоп приложение на python-1 1. картинка десктоп приложение на python. картинка 1 1.

Пример веб-браузера, разработанного с помощью Python и Qt. Модуль QtWebEngineWidgets, представленный в Qt 5.6, даёт возможность просматривать веб-страницы в одном окне и использовать привычные элементы управления.

Mozzarella Ashbadger

десктоп приложение на python. 2 1. десктоп приложение на python фото. десктоп приложение на python-2 1. картинка десктоп приложение на python. картинка 2 1.

Mozarella Ashbadger — революция среди браузеров! Возвращайтесь на вкладку назад и вперёд! Печатайте страницы! Сохраняйте файлы! Воспользуйтесь справкой! Любые совпадения с другими браузерами совершенно случайны.

Moonsweeper

десктоп приложение на python. 3. десктоп приложение на python фото. десктоп приложение на python-3. картинка десктоп приложение на python. картинка 3.

Исследуйте таинственную поверхность луны Q’tee, но остерегайтесь пришельцев-аборигенов.

Moonsweeper — игра-головоломка, основанная на известном «Сапёре». Цель игры — исследовать поверхность вокруг зоны приземления вашего космического корабля, избегая встречи со смертоносными пришельцами расы B’ug. Детектор пришельцев подскажет, сколько ксеноморфов находится поблизости.

No2Pads

десктоп приложение на python. 4. десктоп приложение на python фото. десктоп приложение на python-4. картинка десктоп приложение на python. картинка 4.

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

Calculon

десктоп приложение на python. 5. десктоп приложение на python фото. десктоп приложение на python-5. картинка десктоп приложение на python. картинка 5.

Простой калькулятор, интерфейс разработан в Qt Designer, а операции реализованы с помощью стека.

Megasolid Idiom

десктоп приложение на python. 6. десктоп приложение на python фото. десктоп приложение на python-6. картинка десктоп приложение на python. картинка 6.

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

NSAViewer

десктоп приложение на python. 7. десктоп приложение на python фото. десктоп приложение на python-7. картинка десктоп приложение на python. картинка 7.

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

Failamp

десктоп приложение на python. 8. десктоп приложение на python фото. десктоп приложение на python-8. картинка десктоп приложение на python. картинка 8.

Простое приложение для прослушивания аудио и просмотра видео-файлов с поддержкой плейлиста. Для работы с воспроизведением и плейлистом используются QtMultimedia и QtMultimediaWidgets.

Brown Note (QtDesigner)

десктоп приложение на python. 9. десктоп приложение на python фото. десктоп приложение на python-9. картинка десктоп приложение на python. картинка 9.

Это приложение позволяет создавать временные записки на рабочем столе. Записки хранятся в базе данных SQLiteTake.

Piecasso (QtDesigner)

десктоп приложение на python. 10. десктоп приложение на python фото. десктоп приложение на python-10. картинка десктоп приложение на python. картинка 10.

Проявите свою творческую натуру с PieCasso — единственным приложением для рисования со встроенными рисунками пирога.

Piecasso — клон Paint из Windows 95 с несколькими новыми функциями и вырезанными старыми. В программе доступны стандартные инструменты вроде кисти, карандаша, заливки, распылителя и множество фигур.

7Pez (QtDesigner)

десктоп приложение на python. 11. десктоп приложение на python фото. десктоп приложение на python-11. картинка десктоп приложение на python. картинка 11.

Распаковывайте архивы с помощью кота. Перетащите архив на кота и нажмите на его голову, чтобы распаковать архив в той же папке.

Translataarrr (QtDesigner)

десктоп приложение на python. 12. десктоп приложение на python фото. десктоп приложение на python-12. картинка десктоп приложение на python. картинка 12.

Переводчик с любого языка, поддерживаемого Google Translate, на пиратский. В приложении используются API для funtranslations.com и неофициальная обёртка над Google Translate для перевода на английский с других языков.

Raindar (QtDesigner)

десктоп приложение на python. 13. десктоп приложение на python фото. десктоп приложение на python-13. картинка десктоп приложение на python. картинка 13.

Приложение, показывающее прогноз погоды в выбранном городе. Данные для прогноза берутся через API для OpenWeatherMap.

Doughnut (PyQtGraph)

десктоп приложение на python. 14. десктоп приложение на python фото. десктоп приложение на python-14. картинка десктоп приложение на python. картинка 14.

Это приложение с помощью API для Fixer позволяет отслеживать курсы валют. По умолчанию отображаются курсы за последние полгода.

Ronery (QGraphicsScene)

десктоп приложение на python. 15. десктоп приложение на python фото. десктоп приложение на python-15. картинка десктоп приложение на python. картинка 15.

Клон игры «Косынка» с Ким Чен Иром на рубашке карт. На внешнем виде различия между играми заканчиваются. В Ronery для работы с игровым полем используется QGraphicsScene.

Источник

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

Авторизуйтесь

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

десктоп приложение на python. py qt designer 1. десктоп приложение на python фото. десктоп приложение на python-py qt designer 1. картинка десктоп приложение на python. картинка py qt designer 1.

Эта статья предназначена для тех, кто только начинает своё знакомство с созданием приложений с графическим интерфейсом (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 придётся устанавливать через терминал. Установить всё, что нам понадобится, одной командой можно, например, так:

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

Дизайн

Основы

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

25–26 ноября, Москва и онлайн, От 24 000 до 52 000 ₽

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

десктоп приложение на python. Screenshot 20180324 224050. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 224050. картинка десктоп приложение на python. картинка Screenshot 20180324 224050.

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

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

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

десктоп приложение на python. Screenshot 20180324 225724. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 225724. картинка десктоп приложение на python. картинка Screenshot 20180324 225724.

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

Макеты

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

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

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

десктоп приложение на python. Screenshot 20180324 224534. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 224534. картинка десктоп приложение на python. картинка Screenshot 20180324 224534.

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

десктоп приложение на python. Screenshot 20180324 224555. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 224555. картинка десктоп приложение на python. картинка Screenshot 20180324 224555.

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

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

десктоп приложение на python. Screenshot 20180324 224725. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 224725. картинка десктоп приложение на python. картинка Screenshot 20180324 224725.

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

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

десктоп приложение на python. Screenshot 20180324 225015. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 225015. картинка десктоп приложение на python. картинка Screenshot 20180324 225015.

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

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

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

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

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

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

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

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

десктоп приложение на python. Screenshot 20180324 225310. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 225310. картинка десктоп приложение на python. картинка Screenshot 20180324 225310.

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

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

Пишем код

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

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

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

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

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

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

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

десктоп приложение на python. Screenshot 20180324 225529. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 225529. картинка десктоп приложение на python. картинка Screenshot 20180324 225529.

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

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

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

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

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

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

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

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

десктоп приложение на python. Screenshot 20180324 225614. десктоп приложение на python фото. десктоп приложение на python-Screenshot 20180324 225614. картинка десктоп приложение на python. картинка Screenshot 20180324 225614.

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

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

Источник

Десктопное приложение на Python: UI и сигналы

Авторизуйтесь

Десктопное приложение на Python: UI и сигналы

Считается, что Python не лучший выбор для десктопных приложений. Однако, когда в 2016 году я собирался переходить от разработки сайтов к программному обеспечению, Google подсказал мне, что на Python можно создавать сложные современные приложения. Например blender3d, который написан на Python.

десктоп приложение на python. blender. десктоп приложение на python фото. десктоп приложение на python-blender. картинка десктоп приложение на python. картинка blender.
Но люди, не по своей вине используют уродливые примеры графического интерфейса, которые выглядят слишком старыми, и не понравятся молодёжи. Я надеюсь изменить это мнение в своем туториале. Давайте начнём.

Мы будем использовать PyQt (произносится «Пай-Кьют‎»‎). Это фреймворк Qt, портированный с C++. Qt известен тем, что необходим C++ разработчикам. С помощью этого фреймворка сделаны blender3d, Tableau, Telegram, Anaconda Navigator, Ipython, Jupyter Notebook, VirtualBox, VLC и другие. Мы будем использовать его вместо удручающего Tkinter.

Требования

Установка

Вам нужно установить только PyQt. Откройте терминал и введите команду:

Мы будем использовать PyQt версии 5.15. Дождитесь окончания установки, это займёт пару минут.

Hello, World!

Создайте папку с проектом, мы назовём его helloApp. Откройте файл main.py, лучше сделать это vscode, и введите следующий код:

Этот код вызывает QGuiApplication и QQmlApplicationEngine которые используют Qml вместо QtWidget в качестве UI слоя в Qt приложении. Затем, мы присоединяем UI функцию выхода к главной функции выхода приложения. Теперь они оба закроются одновременно, когда пользователь нажмёт выход. Затем, загружаем qml файл для Qml UI. Вызов app.exec(), запускает приложение, он находится внутри sys.exit, потому что возвращает код выхода, который передается в sys.exit.

Добавьте этот код в main.qml:

Этот код создает окно, делает его видимым, с указанными размерами и заголовком. Объект Text отображается в середине окна.

27–28 ноября, Москва, Беcплатно

Теперь давайте запустим приложение:

Вы увидите такое окно:

десктоп приложение на python. hello world window. десктоп приложение на python фото. десктоп приложение на python-hello world window. картинка десктоп приложение на python. картинка hello world window.
Обновление UI

Давайте немного обновим UI, добавим фоновое изображение и время:

Внутри типа ApplicationWindow находится содержимое окна, тип Rectangle заполняет пространство окна. Внутри него находится тип Image и другой прозрачный Rectangle который отобразится поверх изображения.

Если сейчас запустить приложение, то текст появится в левом верхнем углу. Но нам нужен левый нижний угол, поэтому используем отступы:

После запуска вы увидите следующее:

десктоп приложение на python. python time screenshot autoconverted. десктоп приложение на python фото. десктоп приложение на python-python time screenshot autoconverted. картинка десктоп приложение на python. картинка python time screenshot autoconverted.
Показываем текущее время

Модуль gmtime позволяет использовать структуру со временем, а strftime даёт возможность преобразовать её в строку. Импортируем их:

Теперь мы можем получить строку с текущим временем:

Строка «%H:%M:%S» означает, что мы получим время в 24 часовом формате, с часами минутами и секундами (подробнее о strtime).

Давайте создадим property в qml файле, для хранения времени. Мы назовём его currTime.

Теперь заменим текст нашей переменной:

Теперь, передадим переменную curr_time из pyhton в qml:

Это один из способов передачи информации из Python в UI.

Запустите приложение и вы увидите текущее время.

Обновление времени

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

Чтобы использовать сигналы нам нужен подкласс QObject. Назовём его Backend.

У нас уже имеется свойства для строки со временем curr_time, теперь создадим свойство backend типа QtObject в файле main.qml.

Передадим данные из Python в qml:

В qml файле один объект QtObject может получать несколько функций (называемых сигналами) из Python.

Создадим тип Connections и укажем backend в его target. Теперь внутри этого типа может быть столько функций, сколько нам необходимо получить в backend.

Таким образом мы свяжем qml и сигналы из Python.

Мы используем потоки, для того чтобы обеспечить своевременное обновление UI. Создадим две функции, одну для управления потоками, а вторую для выполнения действий. Хорошая практика использовать в названии одной из функций _.

Создадим pyqtsignal и назовём его updated, затем вызовем его из функции updater.

В этом коде updated имеет параметр arguments, который является списком, содержащим имя функции «updater». Qml будет получать данные из этой функции. В функции updater мы вызываем метод emit и передаём ему данные о времени.

Обновим qml, получив сигнал, с помощью обработчика, название которого состоит из «on» и имени сигнала:

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

Функция bootUp должна быть вызвана сразу же после загрузки UI:

Всё готово

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

Так должен выглядеть файл main.py:

Вот содержимое файла main.qml:

Сборка приложения

Для сборки десктопного приложения на Python нам понадобится pyinstaller.

Чтобы в сборку добавились все необходимые ресурсы, создадим файл spec:

Настройки файла spec

Параметр datas можно использовать для того, чтобы включить файл в приложение. Это список кортежей, каждый из которых обязательно должен иметь target path(откуда брать файлы) и destination path(где будет находится приложение). destination path должен быть относительным. Чтобы расположить все ресурсы в одной папке с exe-файлами используйте пустую строку.

Измените параметр datas, на путь к вашей папке с UI:

Параметр console установим в false, потому что у нас не консольное приложение.

Параметр name внутри вызова Exe, это имя исполняемого файла. name внутри вызова Collect, это имя папки в которой появится готовое приложение. Имена создаются на основании файла для которого мы создали spec — main.py.

Теперь можно запустить сборку:

В папке dist появится папка main. Для запуска программы достаточно запустить файл main.exe.

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

десктоп приложение на python. build python autoconverted. десктоп приложение на python фото. десктоп приложение на python-build python autoconverted. картинка десктоп приложение на python. картинка build python autoconverted.

О том, как использовать Qt Designer для создания UI приложений на Python читайте в нашей статье.

Источник

О разработке одного desktop-приложения на Python

Всем привет. В этой статье я хочу рассказать о разработке программы с открытым исходным кодом для оффлайнового хранения заметок — OutWiker. Этим проектом я занимаюсь в свободное время, первая версия программы вышла в далеком 2010 году, и OutWiker до сих пор продолжает развиваться. Так уж исторически сложилось, что кодом я занимаюсь практически в одиночку (хотя изредка получаю полезные отдельные патчи), но зато пользователи активно участвуют в переводе программы на свой родной язык и иногда присылают стили оформления для страниц, которые затем я включаю в сборку. А уж о том, сколько интересных идей они присылают, и говорить не стоит.

Что такое OutWiker

Когда-то я писал об этой программе на Хабре, но это было так давно, что прежде чем говорить об особенностях внутреннего устройства и процесса разработки, нужно сказать, что представляет собой программа с точки зрения пользователя. Все ссылки, связанные с проектом даны в конце статьи. Итак, OutWiker — это программа для хранения заметок в виде дерева, в англоязычном интернете такой софт обычно называют outliner (поэтому у программы такое название). Среди более известных «коллег» OutWiker с подобным функционалом можно назвать Zim, WikidPad, CherryTree, и множество других (ну и, разумеется, org mode для Emacs). Логичный вопрос с точки зрения пользователя — чем OutWiker отличается от других представителей древовидных записных книжек. На данный момент, по прошествии такого количества времени с момента начала разработки, я уже не готов развернуто сравнить весь этот софт. В стародавние времена я перепробовал десятки outliner-ов, штук пять использовал достаточно долгое время, но везде чего-то не хватало, хотелось одну возможность взять из WikidPad, другую — из викидвижка, который может работать оффлайново и т.д. Поэтому в качестве ответа на такой вопрос просто перечислю основные особенности, которыми обладает OutWiker.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

Кое-что о внутренней кухне разработки

Язык и основные библиотеки

Теперь я расскажу, как OutWiker устроен изнутри, а также с какими проблемами пришлось столкнуться при разработке.

Весь проект написан на Python, причем на Python 2.7, переход на Python 3.x планируется, но не в ближайшее время (почему, скажу чуть позже). Для создания интерфейса используется библиотека wxPython. На этапе зарождения проекта в качестве библиотеки для интерфейса выбирал между wxPython и PyQt, остальные подобные библиотеки были отвергнуты, потому что они создают интерфейс, который выглядит чужеродно или под Windows, или под Linux, и может быть и там, и там. В результате остановился на wxPython из-за того, что размер программы получался меньше. Точные цифры размеров я уже не назову, да и проект с того времени уже сильно разросся. Выбором wxPython я доволен, хотя с ней были связаны некоторые неприятные моменты (о них тоже скажу позже).

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

Что касается кроссплатформенности, то в программе не так много мест, работа которых зависит от операционной системы, и все они связаны с интерфейсом. Пожалуй, наибольшее различие заключается в способе отображения HTML-страниц. Под Windows используется движок Internet Explorer, а под Linux — WebKit. Раньше OutWiker работал под wxPython 2.8 и движки Internet Explorer и WebKit использовались с помощью хаков, которые перестали быть актуальными с выходом wxPython 3.0, теперь классы для работы с этими движками встроены в библиотеку. Правда, Internet Explorer я продолжаю использовать через хак с вызовом COM-объекта, потому что такое использование дает больше возможностей для настроек поведения движка. Теоретически у класса wx.html2.WebView, который должен под Windows работать через Internet Explorer, а под Linux через WebKit, есть метод GetNativeBackend(), который должен вернуть указатель на «настоящий» движок, но почему-то у меня этот метод всегда возвращал None.

Надо признаться, что на проект большое влияние оказала программа WikidPad. Я сам ей долго пользовался, она тоже написана на Python + wxPython, и иногда я даже подсматривал в ее исходники, чтобы посмотреть, как некоторые моменты там сделаны. Надо сказать, что такое подсматривание сэкономило немало времени.

Викинотация

Для страниц с оформлением предназначены три типа страниц: HTML-страницы, Markdown-страницы (требуется добавить соответствующий плагин) и викистраницы. То, что в программе должны быть викистраницы я решил с момента зарождения проекта. В отличие от HTML, викинотации более лаконичны и их легко расширять, добавляя новые команды. Другое преимущество викинотаций — это возможность преобразования встроенного текстового описания в некий графический объект. Например, в OutWiker есть команда для вставки формул в формате LaTeX, вставки графиков, которые строятся либо по данным из текстового файла, либо по данным, которые вставлены непосредственно в код страницы, есть плагин, который из текстового описания создает описание диаграмм и т.п. Кроме того, поскольку викистраница в итоге преобразуется в HTML для отображения пользователю, то это тоже можно использовать, например, при подготовке статей на сайт, если движок сайта ожидает ввода в формате HTML. Например, сейчас эту статью я пишу в виде викинотации, а в конце переключусь на вкладку HTML и получу готовый HTML-код, который нужно будет только немного подогнать под особенности конкретного сайта.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

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

Кстати, в OutWiker не обязательно запоминать викинотацию, все элементы оформления можно вставлять через меню или с помощью панели инструментов. Для HTML- и Markdown-страниц такие кнопки и пункты меню тоже имеются.

Для создания википарсера используется очень удобная библиотека pyparsing. Удобная она в первую очередь тем, что представляет собой всего лишь один файл pyparsing.py, который можно положить в исходники и не тянуть лишнюю зависимость в проекте. С помощью этой библиотеки описываются все используемые токены викинотации, а затем они преобразуются в HTML. Про pyparsing есть подробная документация с множеством примеров и даже небольшая книжка. Кроме того, автор библиотеки активно участвует на форуме на сайте и готов помочь с использованием библиотеки.

Локализация

Над переводом OutWiker на другие языки активно работают некоторые пользователи, за что им огромное спасибо. Для совместного перевода используется сервис crowdin.com. Это достаточно удобный сервис, на котором пользователи могут предлагать свои варианты перевода фраз, обсуждать их.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

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

Вот, например, как выглядит украинская и шведская локализация.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

Для использования локализаций внутри OutWiker используется стандартный модуль gettext.

Особенности сборки

Поскольку Python — интерпретируемый язык программирования, то для того, чтобы пользователь мог запустить программу, теоретически у него должны быть установлены Python и все необходимые библиотеки. Разумеется, заставлять обычных пользователей устанавливать Python, wxPython и другие требуемые библиотеки, да еще и нужных версий, негуманно. Пользователь должен скачать программу, распаковать ее установить с помощью инсталятора и метода «Next — Next — Next», после чего запустить иконку на рабочем столе. К счастью, для программ, написанных на Python, это все делается сравнительно просто. Если говорить про Windows, то интерпретатор Python без стандартных библиотек умещается в dll-ку размером чуть больше 3 МБ. Существуют несколько утилит, которые делают запускаемые файлы (exe-шники, если говорить про Windows) из Python-скриптов. Наиболее известные из них — cx_Freeze и pyInstaller. По возможностям они примерно равноценны (хотя pyInstaller позволяет создавать единственный exe-шник из Python-скрипта, а у cx_Freeze такой возможности нет), но у них разных подход к тому, где хранить файлы *.pyc библиотек, и по поводу того, как задавать параметры сборки.

Для создания exe-шников OutWiker долгое время использовался cx_Freeze. Проблем с ним не было, пока не вышел cx_Freeze 5.0, в этой версии автор сильно переписал внутренности утилиты. Видно из-за этого что-то пошло не так. Сборка OutWiker, созданная с помощью cx_Freeze 5.0 начала виснуть при старте, причем судя по результатам отладки, на ровном месте, где никаких проблем не ожидается (скорее всего это как-то было связано с многопоточностью). После выхода cx_Freeze 5.0.2 эта проблема исчезла, но OutWiker перестал выгружаться из памяти при закрытии программы. Эту проблему можно было решить явным вызовом sys.exit(0) в конце программы, но это костыль, который не хотелось добавлять. К тому же, кто знает, какие еще проблемы могли возникнуть при использовании cx_Freeze 5.0.x. Можно было бы остаться на проверенной временем cx_Freeze 4.x, но я не люблю использовать устаревшие библиотеки. Тогда было решено перейти на pyInstaller. Переезд оказался достаточно быстрым, буквально за один день. Никаких проблем с новой сборкой не возникло. Поэтому теперь для сборки используется pyInstaller. С точки зрения пользователей внешне ничего не должно поменяться.

Те же самые cx_Freeze / pyInstaller можно использовать и для создания бинарных сборок под Linux, чтобы полученная сборка могла запускаться в разных дистрибутивах Linux. Под Windows из полученной сборки создается инсталятор с помощью Inno Setup, а под Linux из подобной сборки создается deb-пакеты (на виртуальных машинах, что будет описано ниже).

Другая особенность сборки заключается в том, как запускаются разные цели сборки. Все начиналось с небольшого Makefile, который постепенно рос, и проблем с ним становилось все больше. В основном они были связаны с кроссплатформенностью — поддерживать единый Makefile под Windows и Linux было тяжело. В свое время мне это надоело и я начал искать альтернативу, желательно, чтобы она была написана на Python. Альтернатива нашлась достаточно быстро в виде программы Fabric. Теперь все бывшие цели Makefile переписаны в обычные функции Python, да и вообще система сборки разрослась неимоверно. Вот, например, как сейчас выглядит список задач Fabric.

Как видите, команд достаточно много, все они описаны в документации. Сюда входят команды для сборки под Windows и Linux, запуска тестов, работы с виртуальными машинами для сборки, обновления локализаций, выкладывания новых версий на сайт и другие. Несмотря на то, что, судя по документации, Fabric больше ориентирован на работу с удаленными серверами (условный аналог Ansible), но в качестве замены Makefile мне он очень нравится.

Войны с Ubuntu

С wxPython были связаны еще несколько неприятных моментов, которые, к счастью, удалось достаточно быстро решить. Все эти проблемы возникали под Ubuntu, на которую я в первую очередь ориентируюсь при разработке (из-за того, что у меня это основная операционная система). Первый неприятный момент был связан с переходом с wxPython 2.8 на 3.0 (не путать с Python 3.x). Дело в том, что при переходе с версии 2.8 к 3.0 были некоторые проблемы с обратной совместимостью, но, к счастью, эти две версии можно было ставить одновременно и из python-скрипта выбирать нужную версию с помощью wxversion. (с выходом wxPython 4.0 такой возможности больше не будет). Поскольку Python — интерпретируемый язык, и в Ubuntu он всегда присутствует, то для запуска под этой операционной системой нет необходимости создания бинарных сборок, а просто при установке deb-пакета исходники раскидываются по нужным папкам и запускаются с помощью команды python runoutwiker.py. Все необходимые библиотеки для работы wxPython и WebKit указаны как зависимости. Однако с выходом Ubuntu 16.04 LTS возникли две проблемы. Первая была связана с тем, что в этой версии Ubuntu убрали wxPython 2.8, поэтому пришлось срочно мигрировать на wxPython 3.0 и отказаться от поддержки другой долгоживущей версии Ubuntu 14.04 LTS. Но это еще не все, оказалось, что в Ubuntu 16.04 (в следующих версиях это исправили) wxPython как-то неправильно скомпилирован, и в нем без шаманств не работает движок WebKit. К счастью, тут помогли продвинутые пользователи OutWiker, которые подсказали, что проблема обходится с помощью LD_PRELOAD и указанием пути до одной библиотеки, относящейся к wxPython. Как я уже сказал, надобность в этом костыле в последующих версиях Ubuntu отпала, но ради поддержки Ubuntu 16.04 его приходится использовать до сих пор.

Чтобы в будущем обезопасить себя и пользователей от подобных изменений в Ubuntu, недавно начал делать бинарные сборки под Linux. Такие сборки делаются для 32- и 64-битных систем. В перспективе это позволит самостоятельно компилировать wxPython с нужными параметрами и не зависеть от имеющихся библиотек в репозиториях Ubuntu. Для того, чтобы создавать бинарные сборки (и deb-пакеты на основе их) используется связка Ansible, Vagrant и VirtualBox. С помощью Vagrant запускаются две виртуальные машины (32 и 64 бита), туда с помощью Ansible через SSH закачиваются исходники программы, там создаются бинарные сборки и deb-пакеты, которые скачиваются обратно на рабочий комп (хост). Но недавно и тут разработчики Ubuntu подложили свинью. Дело в том, что виртуальные машины создаются на основе Ubuntu 17.04, и в перспективе я собирался переводить виртуальные машины на Ubuntu 17.10. Я бы рад был использовать для сборки версию Ubuntu 16.04 LTS, но, как я уже говорил, там есть проблемы с wxPython. Но внезапно разработчики Ubuntu решили отказаться от поддержки 32-битных систем. Возможно, в будущем для сборки на виртуальных машинах придется переходить на другой дистрибутив. Конечно, можно было бы тоже отказаться от поддержки 32-битных систем, но в данный момент такая поддержка мне как разработчику не мешает, а пользователям может быть полезна.

Другие используемые библиотеки

Кроме уже упоминавшихся библиотек wxPython и pyparsing в проекте используются и другие библиотеки. Коротко перечислю их.

Планы на дальнейшее развитие

Проект OutWiker активно развивается, доказательство чему статистика коммитов на github:

десктоп приложение на python. image loader. десктоп приложение на python фото. десктоп приложение на python-image loader. картинка десктоп приложение на python. картинка image loader.

Сейчас исходники занимают около 90 МБ, куда входят почти 4300 файлов, из них 1772 — python-скрипты.

Планов и идей огромное количество (количество issues на github сейчас чуть меньше 350). Туда попадают любые пожелания пользователей, даже если в ближайшее время до их реализации руки точно не дойдут. Поскольку кодом занимаюсь я практически в одиночку, то новые возможности появляются не так быстро, как хотелось бы. В последнее время стабильные версии OutWiker выходят примерно раз в год, но каждый месяц я выкладываю нестабильные версии. На самом деле их нестабильность — вопрос философский, потому что я не выкладываю откровенно неработающие версии, и иногда нестабильные версии «стабильнее» стабильных в том плане, что после релиза в них исправляются какие-то найденные не критичные недоработки из последнего релиза. Но в нестабильных версиях я могу себе позволить что-то не успеть отшлифовать, а может быть что-то не заметить после добавления новой возможности.

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

В свете описанных выше вечно возникающих проблем с Ubuntu хочется попробовать под Linux сделать snap-пакет или/и flatpak-пакет.

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

В более дальней перспективе нужно будет перейти на wxPython 4.0, который, надеюсь, скоро получит статус релиза, и на Python 3.x. Логично сначала будет перейти на wxPython 4.0, который поддерживает обе версии Python, а потом перейти на Python 3.

Источник

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

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