pyqt-crom
pyqt-crom copied to clipboard
Create cross-platform apps (Android for now) using only Python and the Qt Framework (PyQt5 for now).
PyQt-CroM
What is it?
A tool to create cross-platform apps using only Python and the Qt Framework.
PyQt-CroM demonstrates the capabilities of pyqtdeploy and optimises its use.
Who is it for?
PyQt-CroM is mainly aimed at the following groups.
Why bother?
There are various reasons to create yet another cross-platform app generation tool (especially based on Python and the Qt framework):
-
Javascript is the current leading language for cross-platform app development frameworks (e.g. React Native, Nodejs, Ionic). However,
Javascript is harder to pick up and learn for beginners than Python. Furthermore, Python comes with built-in modules and an extensive list of libraries, whereas Javascript only comes with a few powerful libraries, which makesJavascript still less handy and less flexible for intermediate and expert developers. -
Flutter is gaining traction in the cross-platform ecosystem, as it is fast, flexible and allows native feature access. Its base language is Dart language, which is easy to learn, fast, performant and documented, but
Dart suffers from a lack of online resources and community support(as it is fairly recent). On the contrary, Python benefits from countless useful online resources, as well as a large and active community. -
No-code or low-code platforms (e.g. Bubble) are a great option for beginners as they help them prototype quickly, but
no-code platforms are very limited in functionalities sought after by intermediate and expert developers. Some platforms (e.g. FlutterFlow) enable the use of code to extend existing capabilities, but this increases the the level of access requirements for beginners. Python is a great competitor to low-code platforms as it is accessible to beginners, and is also a great competitor to more advanced platforms, as it boasts a large range of libraries, making it easy to customise features and create advanced functionalities. -
Kivy and BeeWare are the most famous cross-platform app development frameworks based on Python. Even though Kivy is more focused on non-native user interface and BeeWare is more focused on native feel,
Kivy and BeeWare can't provide native and non-native feel in one framework simultaneously. Furthermore, they both lack community support and good documentation. On the contrary, PyQt relies relies on the Qt framework which is the leader in GUI apps (thanks to an active community) and allows to develop apps with a native feel (QtWidgets) or a more custom and standardised look (QtQuick) according to Qt framework comparison. -
Tkinter relies on Python and the code is stable, however
the user interface in Tkinter is not appealing and the code is hard to debug. On the contrary, PyQt makes Qt components directly accessible from the Python language, which makes it easy to organise, customise and debug code (thanks to recognised Qt expertise). -
PySide is developed by Qt, but surprisingly requires a lot of setup and various tools to convert from a script to a mobile app for instance, as expressed by Qt itself on Qt website. Even though pyqtdeploy also requires a lot of setup to convert a PyQt script into a cross-platform app, the process is robust and reliable.
:heavy_check_mark: The tool pyqtdeploy is still not perfect, but the limitations are non-critical for the target audience:
- Qt documentation is great for C++, but less for Python
- Pyqtdeploy documentation is almost non-existent
- The size of generated apps is usually bigger than expected, because they need to include a Python interpreter if not available on the OS (e.g. Android apps).
The aforementioned limitations constitute obstacles that can be tackled by PyQt-CroM.
Table of Contents
- Overview
- 1. Getting started
- 1.1. Check the pre-requisites
- 1.2. Download the github repo
- 1.3. Setup the path to the main repo
- 1.4. Setup the python virtual environment
- 1.4.1. Create a python virtual environment
- 1.4.2. Activate your virtual environment
- 1.4.3. Install the necessary pip packages
- 1.4.4. Test the demo app in your virtual environment
- 1.5. Install the external dependencies
- 1.5.1. Download a set of external dependencies for pyqtdeploy
- 1.5.2. Install Zlib for pyqtdeploy
- 1.5.3. Install Java for Android Studio
- 1.5.4. Install Android Studio
- 1.5.5. Install correct Android SDK and Tools
- 1.5.6. Install Android NDK matching with Qt version
- 1.5.7. Install Qt from the installer
- 1.6. Setup the environment variables
- 1.7. Build the app with pyqtdeploy
- 1.8. Run the app
- 2. Generating your own app
- 2.1. Create your python package
- 2.2. Update the sysroot
- 2.3. Configure the pdt
- 2.4. Build the app
- 2.5. Debug the app
- 3. Enhancing your app
- 4. Releasing your app
- 5. Troubleshooting
- 6. Roadmap
- 7. Credits
- 8. Support
1. Getting started
:mag: This tutorial guides you through the process of generating a cross-platform app from a simple PyQt5 demo app.
:trophy: By the end of the tutorial, you will be able to launch the simple PyQt5 demo app from your Android phone:
1.1. Check the pre-requisites
Specs of Linux machine used:
Ubuntu 22.04(EOL April 2032) with around 40-50GB available (to install the dependencies)Python 3.10.12(EOL October 2026) pre-installed on Ubuntu 22
:bulb: Refer to Virtual Machine Setup if you don't have a Linux OS available on your machine.
Specs of target OS:
Android 9.0as targeted Android features (default)Android 9.0as minimum Android version to run the app (default)
1.2. Download the github repo
Use the HTTPS method if you don't have a Github account:
cd $HOME/Documents \
&& git clone https://github.com/achille-martin/pyqt-crom.git
Use the SSH method if you have a Github account (and SSH key setup):
cd $HOME/Documents \
&& git clone [email protected]:achille-martin/pyqt-crom
1.3. Setup the path to the main repo
:warning: We will use PYQT_CROM_DIR as the variable containing the path to the main repo.
Add the variable to your .bashrc with:
printf "%s\n" \
"" \
"# Environment variable for PyQt-CroM path" \
"export PYQT_CROM_DIR=$HOME/Documents/pyqt-crom" \
"" \
>> $HOME/.bashrc \
&& source $HOME/.bashrc
1.4. Setup the python virtual environment
1.4.1. Create a python virtual environment
sudo apt-get update \
&& sudo apt-get install python3-pip \
&& python3 -m pip install --upgrade pip \
&& sudo apt-get install python3-virtualenv \
&& cd $PYQT_CROM_DIR \
&& mkdir -p venv \
&& cd venv \
&& virtualenv pyqt-crom-venv -p python3 \
&& cd ..
1.4.2. Activate your virtual environment
source $PYQT_CROM_DIR/venv/pyqt-crom-venv/bin/activate
:bulb: To exit the virtual environment, type in your terminal deactivate.
1.4.3. Install the necessary pip packages
Make sure that pip3 (pip for python3) has been upgraded to v23.3.2 (or later) in the virtual environment with:
pip3 --version
If pip3 needs to be upgraded, run the command:
pip3 install --upgrade pip
Install the pip packages in the virtual environment with:
cd $PYQT_CROM_DIR \
&& pip3 cache purge \
&& pip3 install -r requirements.txt
:bulb: You can confirm the installed pip packages with pip3 list --local.
1.4.4. Test the demo app in your virtual environment
cd $PYQT_CROM_DIR/examples/demo/demo_project/demo_pkg \
&& python3 demo_app.py
The PyQt5 demo app will start and you can confirm that it is displayed properly on your machine:
- Click the button
- An alert message is displayed stating that you have clicked the button
1.5. Install the external dependencies
1.5.1. Download a set of external dependencies for pyqtdeploy
Download the sources with:
cd $PYQT_CROM_DIR/utils/resources \
&& chmod +x download_sources.sh \
&& ./download_sources.sh
:bulb: You can confirm that the list of packages required matches with the versions from $PYQT_CROM_DIR/examples/demo/demo_project/sysroot.toml.
1.5.2. Install Zlib for pyqtdeploy
Install zlib on Ubuntu with:
sudo apt install zlib1g-dev
Zlib is required by the pyqtdeploy project $PYQT_CROM_DIR/examples/demo/demo_project/config.pdt to correctly identify the dependencies from the $PYQT_CROM_DIR/examples/demo/demo_project/sysroot.toml.
:bulb: Sysroot setup tips can be obtained from Riverbank website.
1.5.3. Install Java for Android Studio
Install stable java JDK 11 available for your Ubuntu distribution and tested with Gradle:
sudo apt install openjdk-11-jdk openjdk-11-jre
Set the default java and javac version to 11 using:
sudo update-alternatives --config java \
&& sudo update-alternatives --config javac
:hand: Confirm the version with java -version && javac -version which should be v11.0.21.
1.5.4. Install Android Studio
Download Android Studio version 2023.1.1.26 with:
sudo apt-get install wget \
&& cd $HOME/Downloads \
&& wget https://redirector.gvt1.com/edgedl/android/studio/ide-zips/2023.1.1.26/android-studio-2023.1.1.26-linux.tar.gz
Move the contents of the downloaded tar.gz to your $HOME directory using:
cd $HOME/Downloads \
&& tar -xvf android-studio-2023.1.1.26-linux.tar.gz \
&& mv android-studio $HOME
Start the installation with:
cd $HOME/android-studio/bin \
&& ./studio.sh
:bulb: Tip: if there is an issue with android studio start, use sudo ./studio.sh.
The Android Studio installer will start:
- Do not import settings
- Select custom installation if possible
- Pick the default Android SDK
- Deselect Virtual Device if you don't need it for testing
- Keep a note of the Sdk installation path, which should be
$HOME/Android/Sdk - Start the download (unless you want to install extra features)
- Close Android Studio
:hand: Make sure that the default SDK has been installed in $HOME/Android/Sdk and that $HOME/Android/Sdk/platforms contains android-28 folder only.
The reason why android-28 (corresponding to Android v9.0) is selected is because there are restrictions depending on the Java version installed and the Qt version installed.
If $HOME/Android/Sdk/platforms does not contain android-28 folder only, follow the instructions at the next step to set things up correctly.
1.5.5. Install correct Android SDK and Tools
- Restart Android Studio with
cd $HOME/android-studio/bin && ./studio.sh(skip / cancel if no SDK found) - On the menu screen, click on
more actionsand thenSDK manager- Make sure that you are in the Settings -> Languages & Frameworks -> Android SDK
- Make sure that in the
SDK Platformstab, the following is installed (Show package details and unhide obsolete packages): (Android 9.0) Android SDK Platform 28 and Sources for Android 28. - Remove any additional unneeded package from the list.
- Apply changes for
SDK Platformstab. - Make sure that in the
SDK Toolstab, the following is installed (Show package details and unhide obsolete packages): (Android SDK Build-Tools 34) v28.0.3, Android Emulator any version, Android SDK Tools (Obsolete) v26.1.1. - Remove any additional unneeded and interfering package from the list.
- Close Android Studio
- Download SDK Platform-Tools v28.0.3 to match the SDK Build-Tools version and add it to your SDK folder using:
cd $HOME/Downloads \
&& wget https://dl.google.com/android/repository/platform-tools_r28.0.3-linux.zip \
&& sudo apt-get install unzip \
&& unzip platform-tools_r28.0.3-linux.zip \
&& rm -r $HOME/Android/Sdk/platform-tools \
&& mv platform-tools $HOME/Android/Sdk
1.5.6. Install Android NDK working with Qt version
- Restart Android Studio with
cd $HOME/android-studio/bin && ./studio.sh(skip / cancel if no SDK found) - On the menu screen, click on
more actionsand thenSDK manager- Make sure that you are in the Settings -> Languages & Frameworks -> Android SDK
- Make sure that in the
SDK Toolstab, the following is installed: NDK Side-By-Side v21.4.7075529 (equivalent to r21e). According to the Qt Website, this is the one recommended for Qt5.15.2.
- Close Android Studio
:hand: Make sure that $HOME/Android/Sdk/ndk/21.4.7075529/platforms contains the folder android-28.
:bulb: The NDK corresponds to the minimum version required to run the app. Technically, you could choose a lower version than Android API 9.0 (android-28).
1.5.7. Install Qt from the installer
Download the Qt version which matches the one in $PYQT_CROM_DIR/examples/demo/demo_project/sysroot.toml from the open source online installer:
sudo apt-get install libxcb-xfixes0-dev libxcb-xinerama0 \
&& cd $HOME/Downloads \
&& wget https://d13lb3tujbc8s0.cloudfront.net/onlineinstallers/qt-unified-linux-x64-4.6.1-online.run \
&& chmod +x qt*.run \
&& ./qt-unified-linux-x64-4.6.1-online.run
A Qt window will appear on which you can sign up:
- Verify your email and register as an individual (no need for location)
- Restart the Qt installer with:
cd $HOME/Downloads && ./qt-unified-linux-x64-4.6.1-online.run - Log in, state that you are an individual and not a company
- If possible, select "Custom installation" and make sure to only setup
Qt5.15.2(and other packages you might want) - Setup will start
- Select folder location
$HOME/Qt5.15.2 - Installation will start
:hand: Make sure that you can access $HOME/Qt5.15.2/5.15.2 and that the folder android is located inside of it.
:bulb: The package libxcb-xinerama0 is installed to prevent an issue inherent to Qt5.15 (but solved in Qt6) with xcb Qt platform plugin, according to QT DEBUG reports.
1.6. Setup the environment variables
Load the environment variables on terminal startup with:
printf "%s\n" \
"" \
"# Load extra environment variables for PyQt-CroM" \
"source $PYQT_CROM_DIR/utils/resources/path_setup.sh" \
"" \
>> $HOME/.bashrc \
&& source $HOME/.bashrc
1.7. Build the app with pyqtdeploy
Start the building process of the .apk with:
cd $PYQT_CROM_DIR/utils \
&& python3 build_app.py --pdt $PYQT_CROM_DIR/examples/demo/demo_project/config.pdt --jobs 1 --target android-64 --qmake $QT_DIR/android/bin/qmake --verbose
:hourglass_flowing_sand: Let the app build (it may take a while). The app is built when you see "BUILD SUCCESSFUL".
:bulb: The Android Manifest, build.gradle and gradle.properties can be checked at debug stage in $PYQT_CROM_DIR/examples/demo/demo_project/build-android-64/android-build.
1.8. Run the app
The generated DemoCrossPlatformApp.apk can be found in $PYQT_CROM_DIR/examples/demo/demo_project/releases/<build_date>.
You can then either:
- Copy, install and run the .apk onto your phone (>=Android v9.0)
- Install BlueStacks on Windows, enable hyper-V, open
my gamesand install the .apk, run the app offline - Setup a virtual device in Android Studio, install the app and run it on the virtual device
:trophy: Congratulations! You have completed the tutorial. You can view the demo app running on an Android phone.
:arrow_heading_up: Back to TOP
2. Generating your own app
:mag: This section describes the steps to generate an Android app (.apk) from a custom PyQt5 app.
:bulb: Make sure to go through the Getting Started tutorial to correctly setup your machine and environment.
:warning: In this section, placeholders are defined between <>. For instance, <pkg_name> can be demo_pkg or test_pkg.
2.1. Create your python package
Start by creating a project folder:
- Create a folder
<project_name>wherever you want (and remember the absolute path of its parent folder referred to as<absolute_path>)
Inside of the project folder, create a python package to hold your PyQt5 app:
- Create a folder
<project_name>/<pkg_name> - Populate
<project_name>/<pkg_name>with at least__init__.pyfile and a<main_file_name>.pyscript (you can add more files if required by your package)
Note that the <main_file_name>.py must contain a unique main() function (or any similar distinctive entry point).
:bulb: An example of python package is given in the demo project folder.
2.2. Configure the sysroot
Inside of your <project_name> folder, add the sysroot config to specify application dependencies:
- Create a file called
sysroot.tomland populate it with all the modules used by your app.
For instance, if you imported QtSql in your PyQt5 app, then you must include QtSql in [PyQt.android] installed_modules.
:bulb: An example of sysroot config is given in the demo project folder.
2.3. Configure the pdt
Inside of your <project_name> folder, add the pdt config to specify python dependencies and build requests:
- Create a file called
config.pdtand configure it
To configure the config.pdt file, you need to understand and use the various areas shown in the following pictures:
- Open the
config.pdtfile with:cd <absolute_path>/<project_name> && pyqtdeploy config.pdt. - [AREA 1] In the
Application source tab > Name area, add the<app_name>with no spaces. This is the app name shown at export time. - [AREA 2] In the
Application source tab, click on theScanbutton to select your<project_name>/<pkg_name>folder. - [AREA 3] In the
Application source tab > Application Package Directory area, tick the files and folders you want to include into your application. - [AREA 4] In the
Application source tab > Entry point area, add the<pkg_name>.<main_file_name>:mainto tell where the entry point of your application is.
- [AREA 5] In the
Packages tab > Sysroot specification file area, click on the file icon to the right to select the desiredsysroot.tomlfile. - [AREA 6] In the
Packages tab > Standard Library area, tick all the python libraries you have imported in your python application. You can leave the coloured blocks as they import required libraries to build the python application. - [AREA 7] In the
Packages tab > Core Packages area, tick all the external packages that you have imported in your python application. You can leave the coloured blocks as they import required libraries to build the python application. - Save the
config.pdtwithCtrl + Sand close it.
:bulb: An example of pdt config is given in the demo project folder.
:bulb: For more information about pdt files, read the Riverbank website page.
2.4. Build the app
Generate the <app_name>.apk file using:
cd $PYQT_CROM_DIR/utils \
&& python3 build_app.py --pdt <absolute_path>/<project_name>/config.pdt --jobs 1 --target android-64 --qmake $QT_DIR/android/bin/qmake --verbose
:bulb: The <app_name>.apk can be found in the <absolute_path>/<project_name>/releases/<build_date> folder.
2.5. Debug the app
The most nerve-wracking part of deploying an application is the debugging part.
Therefore, make sure that you have added a logger to your application and that you use an Emulator or a physical device to confirm your expectations.
To setup an Emulator, refer to Android Emulator setup.
:arrow_heading_up: Back to TOP
3. Enhancing your app
:mag: This section offers feature examples to enhance your custom PyQt app.
To discover or analyse PyQt5 features, look at the section dedicated to PyQt5 features.
:arrow_heading_up: Back to TOP
4. Releasing your app
:mag: This section provides a detailed tutorial on how to release your custom app onto main app stores.
To learn more about releasing your own app on app stores, follow the online tutorial.
:arrow_heading_up: Back to TOP
5. Troubleshooting
:mag: This section offers advice to get unstuck when creating your app.
To find out about common setup and running issues, look at the section dedicated to Common issues.
:arrow_heading_up: Back to TOP
6. Roadmap
:mag: This section describes the broad roadmap to deliver a functional repo.
:arrow_heading_up: Back to TOP
7. Credits
Repository created and maintained by Achille Martin.
:clap: Gigantic thanks to Phil Thompson, the creator and maintainer of PyQt and pyqtdeploy.
:heartpulse: Sincere thanks to the well-intentioned international developers who create apps benefitting the community.
For more information about licencing details, take a look at the section dedicated to Licencing.
:arrow_heading_up: Back to TOP
8. Support
:star2: Do you feel that you can make progress with your own projects by converting your PyQt5 apps into cross-platform apps?
Please support PyQt-CroM by starring, advertising and sponsoring it.
:open_hands: Do you feel stuck with your projects?
Get customised help from me on LinkedIn.
:arrow_heading_up: Back to TOP
