basysKom AnwendungsEntwicklung

PySide6, Qt for Python
Essential Summary
In this article, we’re going to have a look at Qt for Python, how it integrates with Qt Creator, and why you might want to consider using it, too.

Interested in Qt for Python? Let me tell you what I learned during the past couple of months using it. I’ve had the opportunity to work on a project based on PySide6, the official Python bindings for Qt 6. I’ve always wanted to get more familiar with Python, so combining that with Qt, something I’m deeply familiar with, was the perfect chance to do so.

PySide6, Qt for Python 1 basysKom, HMI Dienstleistung, Qt, Cloud, Azure

Setting up PySide6 is easy, just create a new virtual environment, activate it, and then install pyside6 through pip. This installs the latest and greatest Qt version together with all the necessary tools. For every Qt tool, there’s a PySide equivalent: pyside6-lupdate, pyside6-lrelease, pyside6-rcc, and so on.

python -m venv env
source env/bin/activate
pip install pyside6 

There’s also a pyside6-uic that takes a UI file created in Qt Designer and creates code from it. Unlike its C++ counterpart, the PySide one of course generates a Python class. Even if you use custom widgets (through “Promote widget”) instead of creating an #include "ui/mywidget.h" directive, it creates a Python from ui.mywidget import MyWidget statement!

A simple “Hello World”-like example could look like this:

#!/bin/env python
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QApplication, QLabel
import sys

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setApplicationDisplayName("Hello, World")

    label = QLabel("Hello from PySide!")
    label.setFont(QFont("Noto Sans", 40))
    label.show()

    app.exec() 

Qt Creator and Python?

Qt Creator also has good support for Qt for Python. Since there’s no QMake or CMake file to list your project’s contents, you can instead create a .pyproject JSON file listing all the relevant files. Conveniently, Qt Creator then also executes the UI compiler and other relevant tools automatically when launching your application. Rather than assigning a compiler and linker to your kit, you manage a Python virtual environment, so every project can have its own clean set of dependencies.
Thanks to Qt Creator’s LSP integration, writing Python is super easy, it just uses pylsp to get autocompletion and warnings as you type. Even if you assign an object somewhere and pass it around five times, it still keeps track of what type it must have been and makes helpful suggestions.
Overall the bindings are fantastic. It’s great that I can think my Qt code through in C++ and then merely write it down in Python syntax. I haven’t encountered a single thing that I could do in C++ that I couldn’t implement using the Python bindings: QAbstractItemModel, QIconEngine, your own QStyledItemDelegate, heck, even a proper QStyle, it’s all possible. The only minor issue I encountered was that type hints don’t participate in method resolution. Unless you use something like plum-dispatch it’s not possible to re-implement only a specific method overload. For example QStyle::polish can take either a QWidget, a QApplication, or a QPalette. A def polish will usually be called in all three cases.
The documentation could also be better, especially for the more exotic use cases (good luck trying to figure out how to do a QMetaObject.invokeMethod with qArg from Python), often it’s just haphazardly auto-translated from C++. Nevertheless, there’s a plethora of example code in Qt’s pyside/examples Git repository to look at.

But Why?

Now that I have convinced you to give PySide6 a try, the obvious question would be: why bother? First of all, Python is very popular in data science and machine learning. If you already have scripts to collect data and analyze it, why not pour it into a beautiful user interface written in Qt without having to learn C++ first?
Something quite neat is that every Python file could have a __main__ entry point. If you place a small QApplication stub with the most basic backend objects required, you can easily run and test individual components detached from the main application. For instance, a dialog or panel that’s like ten clicks away from the main window can just be shown and worked on directly. This encourages better modularization and to integrate components only once they’ve reached a certain level of maturity.
Moreover, Python has a huge ecosystem of 3rd party libraries. Just use SQLAlchemy instad of Qt SQL if that’s what you’re familiar with. Need to parse some YAML files? No problem! Why not take the easy route and use the matplotlib visualization code you have already written and just dump the result into a QWidget? On the other hand, if you rather prefer more Qt-like add-ons, the KDE Frameworks, a set of open-source libraries for Qt, are getting Python bindings as we speak.

Further reading

Picture of Kai Uwe Broulik

Kai Uwe Broulik

Kai Uwe Broulik is Software Architect at basysKom where he designs embedded HMI applications based on Qt with C++ and QML. He also trains customers on how to use Qt efficiently. With his more than ten years of experience in Qt he has successfully deployed Qt applications to a variety of platforms, such as mobile phones, desktop environments, as well as automotive and other embedded devices.

Eine Antwort

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Weitere Blogartikel

basysKom Newsletter

We collect only the data you enter in this form (no IP address or information that can be derived from it). The collected data is only used in order to send you our regular newsletters, from which you can unsubscribe at any point using the link at the bottom of each newsletter. We will retain this information until you ask us to delete it permanently. For more information about our privacy policy, read Privacy Policy