Taking Qt for Python to Android

Deploying Python applications to Android is a big talking point these days among the Python community, and a frequently asked question by people developing their first GUI applications. There are already a couple of Python frameworks that offer the ability to deploy your applications to Android devices, and Qt for Android has existed for a decade now. With QML and Qt Quick, one can use Qt to develop native Android applications. It was high time we bridged the gap and brought PySide applications to Android. 

With the new 6.5 release, we give you a new CLI tool, pyside6-android-deploy, that provides an easy interface to deploy your PySide6 application 🎉. 

Technical Details 

Currently, this tool is only available on Linux-based environments, and only a subset of the Qt modules are supported (see Considerations).  

This tool uses a custom fork of the python-for-android project with a custom Qt bootstrap and recipes for PySide6 and shiboken6. The reason for using python-for-android instead of androiddeployqt is that python-for-android already provides a way to package the Python interpreter, which is by default not pre-installed on Android platforms. It can also be easily extended to include new Python packages, even those with a C/C++ backend. python-for-android already supports many popular Python packages like numpy, pandas, etc. 

The entire deployment process is a 3-step process, where the first two steps need to be done only once per Android platform. The first two steps are setting up and cross-compiling Qt for Python wheels required for pyside6-android-deploy to work.  

Steps to deploy your PySide application to Android 

As mentioned above, Steps 1 and 2 need to be done only once for a specific Android architecture. Each PySide6 application that you deploy will use the same Qt for Python wheels. 

Step 1: Setting up prerequisites 

The Android dependencies for PySide6 are the same dependencies as those for Qt for Android. This step involves downloading the JDK, Android NDK, and Android SDK. You may skip this step if you already have them downloaded and set up. The recommended NDK version for PySide6 version 6.5 is r25. You can either use Qt Creator to install all the dependencies or install the dependencies manually, as shown below.  

1. Install JDK 11 or above. See instructions here.
2. Download the latest version of `Android Command Line Tools Only ` for Linux. This will download a .zip file. 
3. You can use the following script to help you download and setup Android SDK and NDK(r25c) into your current working directory. 

#!/bin/bash 
shopt -s extglob 
if [ -z "$1" ] 
  then 
    echo "Supply path to  commandlinetools-linux-*_latest.zip" 
    exit 1 
fi 
android_sdk=$(pwd)/android_sdk 
mkdir -p $android_sdk 
unzip $1 -d $android_sdk 
latest=$android_sdk/cmdline-tools/latest 
mkdir -p $latest 
mv $android_sdk/cmdline-tools/!(latest) $latest 
$latest/bin/sdkmanager "ndk;25.2.9519653" "build-tools;33.0.2" "platforms;android-31" "platform-tools" 
cp -avr $android_sdk/cmdline-tools/latest $android_sdk/tools

Simply run the script by giving it execution permission (chmod +x) and passing the path to the downloaded .zip file as a cli argument. 

4. Add the Android SDK and NDK paths into the following environment   variables: 

export ANDROID_SDK_ROOT=“/android_sdk” 
export ANDROID_NDK_ROOT=“/android_sdk/ndk/25.2.9519653” 

Step 2: Cross-compile Qt for Python wheels for Android 

Python-for-android requires shiboken6 and PySide6 to be cross-compiled during the deployment process to produce Qt for Python binaries that are compatible with the specific Android platform. Cross-compiling Qt for Python every time for each of your applications can be a cumbersome, time-consuming task 😫. Hence, it is better to use cross-compilation once to create Qt for Python wheels for an Android platform, which can be reused for each of the applications that you deploy. We have made creating these wheels easier for you with a Python script which is available in the Qt for Python source repository.

Make sure to install all the project requirements up to and including “Getting the source”, then install the cross-compilation requirements like this: 

pip install –r tools/cross_compile_android/requirements.txt 

And run the following script:  

python tools/cross_compile_android/main.py --plat-name=aarch64 --ndk-path=$ANDROID_NDK_ROOT --qt-install-path=/opt/Qt/6.5.0 --sdk-path=$ANDROID_SDK_ROOT

In the above command, --plat-name refers to one of aarch64, armv7a, i686, x86_64 depending on the target architecture. --qt-install-path refers to the path where Qt 6.5.0 or later is installed. Use  --help  to see all the other available options.   

After the successful completion of this command, you will have the Qt for Python wheels in `pyside-setup/dist` folder. 

Note: We recommend using venv or virtuanenv

Step 3: Deploy your application - pyside6-android-deploy

For this tutorial, we take a simple QtQuick example Scene Graph Painted Item example.  You can download this example directly from the link. One main requirement of pyside6-android-deploy tool is that the main Python entry point file should be named main.py. Change the name of painteditem.py to main.py and adjust correspondingly in painteditem.pyproject. The requirement of having the main Python entry point named main.py comes from python-for-android. Having the .pyproject file is not a strict requirement, but it enables pyside6-android-deploy to find the files associated with the project more easily and not include any unnecessary files. 

Run the following command: 

pyside6-android-deploy --wheel-pyside=pyside-setup/dist/PySide6-6.5.0a1-6.5.0-cp37-abi3-android_aarch64.whl --wheel-shiboken=pyside-setup/dist/shiboken6-6.5.0a1-6.5.0-cp37-abi3-android_aarch64.whl --name=painteditem  

In the above command --name refers to the application’s name, as shown in your Android device. Use --help to see the other available options. 

At the end of this command, you will have a .apk file created within the application directory, which you can install on your aarch64 based Android device. Hurray, you have successfully taken your Qt for Python application to Android🎉.

Considerations🤔 

1. Presently, the tool `pyside6-android-deploy` only works from Linux.  

     This limitation comes from our cross-compilation infrastructure that we are actively looking to improve and allow macOS and Windows users to also deploy Android applications. 

2. Qt modules supported: QtCore, QtGui, QtWidgets, QtNetwork, QtOpenGL, QtQml,     QtQuick, QtQuickControls2.

3. The main Python entry point of the application should be named main.py 
     This requirement comes from python-for-android. 

What can you expect in the future?🤖

1. More tutorials and examples
     You can expect all the Qt for Android examples to also work and be available for PySide6 Android deployment.

2. Simplifying the current deployment process

3. There are some manual steps that we are aiming to remove, to allow the deployment of applications to be more straightforward.

4.Additional Qt modules compatibility

   There are many examples and real use-case that our Qt for Android offering has, and we want to aim to be compatible with them. That’s why we see value in adding support for QtConcurrent, QtPositioning, QtLocation, QtBluetooth, QtSensors, etc. 


Thank you for reading this tutorial😀. Have fun trying out PySide6 Android deployment. Feel free to drop us a message or open a suggestion/bug in JIRA. Your feedback fuels us in making Qt for Python better. Also, feel open to connecting to the Qt for Python community through our community platforms. 

Stay tuned for further updates on Android deployment 👍. 


Blog Topics:

Comments