Search by Tags

How to build a GUI with Qt for Python and TorizonCore

 

Article updated at 17 Feb 2021
Compare with Revision

Select the version of your OS from the tabs below. If you don't know the version you are using, run the command cat /etc/os-release or cat /etc/issue on the board.



Remember that you can always refer to the Torizon Documentation, there you can find a lot of relevant articles that might help you in the application development.

Torizon 5.0.0

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

    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

Note: 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.

Warning: 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

    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

(Optional) pull the torizon/weston container image:

# docker pull torizon/weston:$CT_TAG_WESTON

Start the weston compositor:

# docker run -d --rm --ipc=host --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 -- --use-pixman

(Optional) pull the torizon/weston-vivante container image:

# docker pull torizon/weston-vivante:$CT_TAG_WESTON_VIVANTE

Start the weston compositor:

Attention: Please, note that by executing the following line you are accepting the terms and conditions of the NXP's End-User License Agreement (EULA)

# docker run -e ACCEPT_FSL_EULA=1 -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-vivante:$CT_TAG_WESTON_VIVANTE --developer weston-launch \
             --tty=/dev/tty7 --user=torizon

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.

Warning: 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.

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

Warning: 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.

Torizon 4.0.0

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.

This article complies to the Typographic Conventions for Torizon Documentation

Prerequisites

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

Please note that the pyside2 and QML requires the following Debian packages:

Dockerfile
RUN apt-get update && apt-get install -y --no-install-recommends \
    python3 \
    qml-module-qtquick2 \
    qml-module-qtquick-controls \
    qml-module-qtquick-controls2 \
    qml-module-qtquick-dialogs \
    python3-pyside2.qtcore \
    python3-pyside2.qtquick \
    python3-pyside2.qtwidgets \
    python3-pyside2.qtgui \
    python3-pyside2.qtqml \
    python3-pyside2.qtnetwork \
    && rm -rf /var/lib/apt/lists/*

Note: 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.

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

    Sample Qt Application

Deployment From the Command-line

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

$ git clone 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:

Start weston using the torizon/arm32v7-debian-weston:buster container image:

# 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 226:* rmw'\
              torizon/arm32v7-debian-weston:buster --developer weston-launch --tty=/dev/tty7 --user=torizon

Start weston using the torizon/arm32v7-debian-weston:buster container image:

# 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 226:* rmw' \
              torizon/arm32v7-debian-weston:buster --developer weston-launch --tty=/dev/tty7 --user=torizon -- --use-pixman

Start weston using the torizon/arm64v8-debian-weston-vivante:buster container image:

Attention: Please, note that by executing the following line you are accepting the terms and conditions of the NXP's End-User License Agreement (EULA)

# docker run -e ACCEPT_FSL_EULA=1 -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/arm64v8-debian-weston-vivante:buster --developer weston-launch --tty=/dev/tty7 --user=torizon

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

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

Warning: 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.

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

Warning: 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.