Skip to content

Latest commit

 

History

History
553 lines (382 loc) · 26.2 KB

README.md

File metadata and controls

553 lines (382 loc) · 26.2 KB

PyQt-CroM

What is it?

A tool to create cross-platform apps using only Python and the Qt Framework.

System Overview Diagram

PyQt-CroM demonstrates the capabilities of pyqtdeploy and optimises its use.

Who is it for?

PyQt-CroM is mainly aimed at the following groups.

Target Audience Overview Diagram

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 makes Javascript 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.

✔️ 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

1. Getting started

🔍 This tutorial guides you through the process of generating a cross-platform app from a simple PyQt5 demo app.

🏆 By the end of the tutorial, you will be able to launch the simple PyQt5 demo app from your Android phone:

pyqt5_demo_app_android.mp4

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

💡 Refer to Virtual Machine Setup if you don't have a Linux OS available on your machine.

Specs of target OS:

  • Android 9.0 as targeted Android features (default)
  • Android 9.0 as 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 git@github.com:achille-martin/pyqt-crom

1.3. Setup the path to the main repo

⚠️ 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

💡 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

💡 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
pyqt5_demo_app_linux.mp4

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

💡 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.

💡 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

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

💡 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

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 actions and then SDK manager
    • Make sure that you are in the Settings -> Languages & Frameworks -> Android SDK
    • Make sure that in the SDK Platforms tab, 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 Platforms tab.
    • Make sure that in the SDK Tools tab, 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 actions and then SDK manager
    • Make sure that you are in the Settings -> Languages & Frameworks -> Android SDK
    • Make sure that in the SDK Tools tab, 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

Make sure that $HOME/Android/Sdk/ndk/21.4.7075529/platforms contains the folder android-28.

💡 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

Make sure that you can access $HOME/Qt5.15.2/5.15.2 and that the folder android is located inside of it.

💡 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

Let the app build (it may take a while). The app is built when you see "BUILD SUCCESSFUL".

💡 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 games and install the .apk, run the app offline
  • Setup a virtual device in Android Studio, install the app and run it on the virtual device

🏆 Congratulations! You have completed the tutorial. You can view the demo app running on an Android phone.

⤴️ Back to TOP

2. Generating your own app

🔍 This section describes the steps to generate an Android app (.apk) from a custom PyQt5 app.

💡 Make sure to go through the Getting Started tutorial to correctly setup your machine and environment.

⚠️ 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__.py file and a <main_file_name>.py script (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).

💡 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.toml and 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.

💡 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.pdt and 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.pdt file 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 the Scan button 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>:main to 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 desired sysroot.toml file.
  • [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.pdt with Ctrl + S and close it.

💡 An example of pdt config is given in the demo project folder.

💡 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

💡 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.

⤴️ Back to TOP

3. Enhancing your app

🔍 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.

⤴️ Back to TOP

4. Releasing your app

🔍 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.

⤴️ Back to TOP

5. Troubleshooting

🔍 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.

⤴️ Back to TOP

6. Roadmap

🔍 This section describes the broad roadmap to deliver a functional repo.

Roadmap Diagram

⤴️ Back to TOP

7. Credits

Repository created and maintained by Achille Martin.

👏 Gigantic thanks to Phil Thompson, the creator and maintainer of PyQt and pyqtdeploy.

💗 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.

⤴️ Back to TOP

8. Support

🌟 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.

👐 Do you feel stuck with your projects?

Get customised help from me on Fiverr.

Buy Me A Coffee

My Fiverr gigs

⤴️ Back to TOP