Skip to main content
Version: 5.0

How to build a GUI with Qt for Python and TorizonCore

Introduction

Qt for Python offers the official Python bindings for Qt (PySide2) to build powerful Graphical User Interfaces (GUI). In this article, we will explain the Qt for Python usage and how you can use it in TorizonCore.

Both QML and Widgets are supported by the Visual Studio Code Extension for Torizon. This article focuses on QML, but while creating a new Torizon project with the extension, you can select a Widget template as a quick start.

This article complies to the Typographic Conventions for Torizon Documentation

Prerequisites

$ pip3 install pyside2

Get Started With VS Code

Follow the articles Visual Studio Code Extension for Torizon and Python Development and Debugging on TorizonCore Using Visual Studio Code. When creating a new Python sample, you will notice that it is possible to select a QML template:

Python Templates

tip

after creating your project from the template, you are ready for development. Everything beyond this point was written before the VS Code templates were added to our extension. Even though the information below may be useful, it is an optional read.

Using Qt for Python - PySide2

Qt for Python project provides pySide2 to implement Qt applications using Python. pySide2 allows access to the complete Qt 5.12+ framework.

A pySide2/QML application requires at least two files:

  • QML file describing the UI
  • Python file loading the QML.

In this article, we will demonstrate a basic Qt for Python project created from scratch. The source code of the example is available on the project's GitHub page.

The QML file

QML is a declarative language to describe the user interface.

The QML file of the sample project describes the existing elements in the UI. For example, to create a button, the following code snippet is used:

usr_interface.qml
Button {
id: button
x: 62
y: 40
width: 94
height: 37
text: qsTr("Temp/Hum")
clip: false
checkable: false
opacity: 1
onClicked: pythonObj.generateEvent()
}

The Python script

In addition to the QML file, it is necessary a Python script to load the QML. In the main Python file of the project, the main function handles the QML file loading.

show_readings.py
if __name__ == '__main__':
appObj = QGuiApplication(sys.argv)
engineObj = QQmlApplicationEngine()

eventObj = EventGenerator()
engineObj.rootContext().setContextProperty("pythonObj", eventObj)

# Load the QML file with the description of the GUI
qmlFile = join(dirname(__file__), 'usr_interface.qml')
engineObj.load(QUrl(qmlFile))

if not engineObj.rootObjects():
sys.exit(-1)

sys.exit(appObj.exec_())

The Dockerfile

See the example Dockerfile on Github for this project. Remember to set the IMAGE_ARCH, IMAGE_NAME and APPNAME variables accordingly to your needs. Set IMAGE_ARCH=linux/arm and IMAGE_NAME=qt5-waylandfor 32-bits SoC (i.MX6, i.MX7) or IMAGE_ARCH=linux/arm64 and IMAGE_NAME=qt5-wayland-vivante for 64-bits SoC (i.MX8).

The proposed Qt application in this article requires the following pyside2 and QML Debian packages as dependencies:

  • python3
  • qml-module-qtquick2
  • qml-module-qtquick-control
  • qml-module-qtquick-controls
  • qml-module-qtquick-dialogs
  • python3-pyside2.qtcore
  • python3-pyside2.qtgui
  • python3-pyside2.qtquick
  • python3-pyside2.qtwidgets
  • python3-pyside2.qtqm
  • python3-pyside2.qtnetwork
info

you may need to add or remove dependencies based on your project's needs. There are several other qml-module-<qml-module-name> and python3-pyside2.<qt-library-binding> packages available.

caution

the current version of package python3-pyside2.qtgui in Debian Bullseye contains a leftover dependency for libqt5gui5. This may cause conflicts when installing the dependencies in containers for devices with Vivante graphics, because these containers require package libqt5gui5-gles instead. The Dockerfile example from Toradex works around this issue by installing an adapted version of python3-pyside2.qtgui.

Running the Sample code

See the Torizon Samples Github Page for an example written in Python, reading temperature and humidity from i2c based sht3x sensor and showing it on the GUI developed using QML.

Sample Qt Application

Deployment From the Command-line

1 - In your development host machine, git clone the Torizon Samples repository:

$ git clone --branch=bullseye https://github.com/toradex/torizon-samples.git

2 - Change to the torizon-samples/python-qml directory. Build the container image.

$ cd torizon-samples/python-qml
$ docker build . -t <your-dockehub-username>/python-qml

3- Push the image to your Dockerhub account:

$ docker push <your-dockehub-username>/python-qml

4- In your board's terminal, pull the Docker container image:

# docker pull <your-dockehub-username>/python-qml

5- The image built with this Dockerfile requires the Qt Wayland container. Therefore, we start the Weston container as the graphics server, as explained on the Qt Debian Container for Torizon, before the application. Select your SoM from the tabs below and follow the instructions:

(Optional) pull the torizon/weston container image:

# docker pull torizon/weston:$CT_TAG_WESTON

Start the weston compositor:

# docker run -d --rm --name=weston --net=host --cap-add CAP_SYS_TTY_CONFIG \
-v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \
--device-cgroup-rule='c 4:* rmw' --device-cgroup-rule='c 13:* rmw' \
--device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' \
torizon/weston:$CT_TAG_WESTON --developer weston-launch --tty=/dev/tty7 --user=torizon
info

To learn more about the device_cgroup_rules section of the docker-compose file above, please refer to the Hardware Access through Control Group Rules (cgroup) section of the Torizon Best Practices Guide

6- Run the sample image:

# docker run --rm -it -v /tmp:/tmp \
-v /dev/dri:/dev/dri --device-cgroup-rule='c 226:* rmw' \
<your-dockehub-username>/python-qml

A window should pop up with a button and two text fields.

Deployment using the Visual Studio Code Extension

tip

this sample predates the VS Code Python templates for Qt available with our extension. It may be easier for you to get started with one of the templates.

First of all, follow the steps from Python Development and Debugging on TorizonCore Using Visual Studio Code.

The same project can also be built/deployed/debugged/released through VScode using the extension for Python.

1 - Git clone the Torizon Samples repository:

$ git clone --branch=bullseye https://github.com/toradex/torizon-samples.git

2 - Create a new Python project on VS Code. See Python Development and Debugging on Torizon Using Visual Studio Code article for detailed instructions on how to start and build a new Python project with Torizon.

caution

Select python3 arm32v7 qt or python3 arm64v8 qt as the base image, depending on the target module.

3 - Add all the files from the folder python-qml/python-qml/app to your VS Code project. You can use the mouse to add and drop these files to your project.

4 - Copy the content from the show_readings.py file to main.py, overwriting the original content of the main.py file. After this, you can remove the show_readings.py file.

5 - On the appconfig_0 folder of the project, create a new file on the VS Code, with the name docker-compose.yml. This Docker Compose file defines the containers to start the TorizonCore Debian With Weston Wayland Compositor Image before to display the Qt application. See the image's .yml sample file for arm64v8 or .yml sample file for arm32v7 as reference.

info

Only the Weston service is needed to be copied to your .yml file.

caution

for iMX8, also add the following lines to the Weston service to accept NXP's EULA required to run Vivante's graphic drivers

docker-compose.yml
environment:
- ACCEPT_FSL_EULA=1

6 - Open the Torizon Configurations view, To do that, press F1 in Visual Studio Code command bar and then type "Torizon/Python: Focus on Configurations View"

7 - On the dockercomposefile property, type docker-compose.yml.

8 - Press F5 to build and run your application.

Send Feedback!