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.

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?
.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. 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. 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.
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?
__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. 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
- Qt for Python: Getting Started https://doc.qt.io/qtforpython-6/gettingstarted.html
- Python with Kirigami: https://develop.kde.org/docs/getting-started/python/
Eine Antwort
That’s really cool to hear, I’ve been wondering what it was like to develop on Qt with Python as well. It’s just way too hard to develop a program in C++ these days.