Understand the requirements to create your own Python package.
Packaging the application
To distribute the application to users we have to package it. We are going to use the setuptools library.
If you'd like to learn more about Python packaging, you'll be interested in the Python Packaging User Guide.
Let's recapitulate what the file structure of the project should be:
simplemdviewer
├── README.md
├── LICENSE.txt
├── MANIFEST.in # To add our QML file
├── pyproject.toml # To declare the tools used to build
├── setup.py # To import setuptools
├── setup.cfg # The setuptools metadata
├── org.kde.simplemdviewer.desktop
├── org.kde.simplemdviewer.json
├── org.kde.simplemdviewer.svg
├── org.kde.simplemdviewer.metainfo.xml
└── src/
├── __init__.py # To import the src/ directory as a package
├── __main__.py # To signal simplemdviewer_app as the entrypoint
├── simplemdviewer_app.py
├── md_converter.py
└── qml/
└── main.qml
Create a simplemdviewer/pyproject.toml to tell the Python build tools what is needed to build our project:
Create a simplemdviewer/setup.py to call setuptools:
from setuptools import setupsetup()
Add a new simplemdviewer/setup.cfg to describe the application:
[metadata]name= org.kde.simplemdviewerversion= 0.1url= https://mydomain.org/simplemdviewerauthor= Example Authorauthor_email= example@author.orgmaintainer= Example Authormaintainer_email= example@author.orgdescription= A simple markdown viewerlong_description= file: README.mdlong_description_content_type= text/markdownclassifiers= Development Status :: 5 - Production/Stable License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) Intended Audience :: End Users/Desktop Topic :: Utilities Programming Language :: Python Operating System :: POSIX :: Linuxkeywords= viewer converter markdown[options]packages= simplemdviewerpackage_dir=simplemdviewer= srcinclude_package_data= Trueinstall_requires= markdown
In the metadata section we have provided information about the application.
Add a new simplemdviewer/org.kde.simplemdviewer.metainfo.xml. This file is used to show the application in app stores.
<?xml version="1.0" encoding="utf-8"?><componenttype="desktop"> <id>org.kde.simplemdviewer</id> <metadata_license>CC0-1.0</metadata_license> <project_license>GPL-3.0+</project_license> <name>Simple Markdown Viewer</name> <namexml:lang="ca">Visualitzador senzill de Markdown</name> <namexml:lang="cs">Jednoduché prohlížení souborů Markdown</name> <namexml:lang="eo">Simpla Markdown-Vidilo</name> <namexml:lang="es">Sencillo visor de Markdown</name> <namexml:lang="fr">Afficheur simple pour langage « Markdown »</name> <namexml:lang="it">Visore Markdown semplice</name> <namexml:lang="ja">シンプルな Markdown ビューアー</name> <namexml:lang="nl">Eenvoudige Markdown-viewer</name> <namexml:lang="sl">Enostavni ogledovalnik Markdown</name> <namexml:lang="sv">Enkel Markdown-visning</name> <namexml:lang="tr">Basit Markdown Görüntüleyicisi</name> <namexml:lang="uk">Простий переглядач Markdown</name> <namexml:lang="x-test">xxSimple Markdown Viewerxx</name> <namexml:lang="zh-TW">簡單 Markdown 檢視器</name> <summary>A simple markdown viewer application</summary> <summaryxml:lang="ca">Una aplicació senzilla de visualització de Markdown</summary> <summaryxml:lang="eo">Simpla markdown-spektila aplikaĵo</summary> <summaryxml:lang="es">Una sencilla aplicación de visor markdown</summary> <summaryxml:lang="fr">Une application d'afficheur simple pour langage « Markdown »</summary> <summaryxml:lang="it">L'applicazione di un visore Markdown semplice</summary> <summaryxml:lang="ja">シンプルな markdown ビューアーアプリケーション</summary> <summaryxml:lang="nl">Een eenvoudige toepassing als Markdown-viewer</summary> <summaryxml:lang="sl">Aplikacija enostavnega ogledovalnika Markdown</summary> <summaryxml:lang="sv">Ett enkelt Markdown-visningsprogram</summary> <summaryxml:lang="tr">Basit bir Markdown görüntüleyici uygulama</summary> <summaryxml:lang="uk">Проста програма для перегляду Markdown</summary> <summaryxml:lang="x-test">xxA simple markdown viewer applicationxx</summary> <summaryxml:lang="zh-TW">一個簡單的 Markdown 檢視器應用程式</summary> <description> <p>Simple Markdown Viewer is a showcase application for QML with Python development</p> <p xml:lang="ca">El visualitzador senzill de Markdown és una aplicació per a presentar el desenvolupament del QML amb el Python</p>
<pxml:lang="eo">Simple Markdown Viewer estas montra aplikaĵo por QML kun Python-evoluo</p> <pxml:lang="es">Sencillo visor de Markdown es una aplicación de demostración para QML con desarrollo en Python</p> <p xml:lang="fr">Un afficheur simple pour langage « Markdown » est une application majeure pour QML pour les développement sous Python</p>
<pxml:lang="it">Visore Markdown semplice è un'applicazione dimostrativa per QML nello sviluppo in Python</p> <pxml:lang="ja">シンプルな Markdown ビューアーは Python 開発による QML のサンプルアプリケーションです。</p> <pxml:lang="nl">Eenvoudige Markdown-viewer is een uitstelkast voor QML met Python ontwikkeling</p> <pxml:lang="sl">Enostavni ogledovalnik Markdown je predstavitvena aplikacija za razvoj QML s Pythonom</p> <pxml:lang="sv">Enkel Markdown-visning är ett förevisningsprogram för QML med Python-utveckling</p> <pxml:lang="tr">Basit Markdown Görüntüleyicisi, Python ile QML geliştirmek için bir vitrin uygulamadır</p> <p xml:lang="uk">Проста програма для перегляду Markdown є прикладом програми для розробки з QML за допомогою Python</p>
<pxml:lang="x-test">xxSimple Markdown Viewer is a showcase application for QML with Python developmentxx</p> <pxml:lang="zh-TW">《簡單 Markdown 檢視器》是用來示範 QML 與 Python 併用開發的應用程式</p> </description> <urltype="homepage">https://mydomain.org/simplemdviewer</url> <releases> <releaseversion="0.1"date="2022-02-25"> <description> <p>First release</p> </description> </release> </releases> <provides> <binary>simplemdviewer</binary> </provides></component>
For this tutorial the well known Markdown icon is okay.
Get the Markdown icon and save it as simplemdviewer/org.kde.simplemdviewer.svg.
We need the icon to be perfectly squared, which can be accomplished with Inkscape:
Open Markdown-mark.svg in Inkscape.
Type Ctrl+a to select everything.
On the top W: text field, type 128 and press Enter.
Go to File -> Document Properties...
Change the Width: text field to 128 and press Enter.
Save the file.
Now we have to let setup.cfg know about the new files. Let’s also provide an easy way to open the application from the console by just typing simplemdviewer.
Update simplemdviewer/setup.cfg to:
[metadata]name= org.kde.simplemdviewerversion= 0.1url= https://mydomain.org/simplemdviewerauthor= Example Authorauthor_email= example@author.orgmaintainer= Example Authormaintainer_email= example@author.orgdescription= A simple markdown viewerlong_description= file: README.mdlong_description_content_type= text/markdownclassifiers= Development Status :: 5 - Production/Stable License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) Intended Audience :: End Users/Desktop Topic :: Utilities Programming Language :: Python Operating System :: POSIX :: Linuxkeywords= viewer converter markdown[options]packages= simplemdviewerpackage_dir=simplemdviewer= srcinclude_package_data= Trueinstall_requires= markdown[options.data_files]share/applications= org.kde.simplemdviewer.desktopshare/icons/hicolor/scalable/apps= org.kde.simplemdviewer.svgshare/metainfo= org.kde.simplemdviewer.metainfo.xml[options.entry_points]console_scripts=simplemdviewer= simplemdviewer.simplemdviewer_app:main
The last step is to tinker with the way we import modules.
Update simplemdviewer/src/simplemdviewer_app.py to
#!/usr/bin/env python3import osimport sysimport signalfrom PySide6.QtGui import QGuiApplicationfrom PySide6.QtCore import QUrlfrom PySide6.QtQml import QQmlApplicationEngine# from md_converter import MdConverterfrom simplemdviewer.md_converter import MdConverter # noqa: F401defmain():"""Initializes and manages the application execution""" app =QGuiApplication(sys.argv) engine =QQmlApplicationEngine()"""Needed to close the app with Ctrl+C""" signal.signal(signal.SIGINT, signal.SIG_DFL)"""Needed to get proper KDE style outside of Plasma"""ifnot os.environ.get("QT_QUICK_CONTROLS_STYLE"): os.environ["QT_QUICK_CONTROLS_STYLE"]="org.kde.desktop" base_path = os.path.abspath(os.path.dirname(__file__)) url =QUrl(f"file://{base_path}/qml/main.qml") engine.load(url)iflen(engine.rootObjects())==0:quit() app.exec()if__name__=="__main__":main()
Create a __main__.py file into the src/ directory. Now that there's a module, this tells the build tools what's the main function, the entrypoint for running the application.
At this point we can tag and release the source code. Linux distributions will package it and the application will be added to their software repositories.