PythonQt
Features

Built-in Features

The following are the built-in features of the PythonQt library:

  • Access all slots, properties, children and registered enums of any QObject derived class from Python
  • Connecting Qt Signals to Python functions (both from within Python and from C++)
  • Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr.
  • Convenient conversions to/from QVariant for PythonQtObjectPtr.
  • Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory
  • Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators)
  • StdOut/Err redirection to Qt signals instead of cout
  • Interface for creating your own import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface)
  • Mapping of plain-old-datatypes and ALL QVariant types to and from Python
  • Support for wrapping of user QVariant types which are registerd via QMetaType
  • Support for Qt namespace (with all enumerators)
  • All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has
  • No preprocessing/wrapping tool needs to be started, PythonQt can script any QObject without prior knowledge about it (except for the MetaObject information from the moc)
  • Multiple inheritance for C++ objects (e.g. if a QWidget is derived from QObject and QPaintDevice, PythonQt will automatically cast a QWidget to a QPaintDevice when needed)
  • Polymorphic downcasting (if e.g. PythonQt sees a QEvent, it can downcast it depending on the type(), so the Python code e.g. sees a QPaintEvent instead of a plain QEvent)
  • Deriving C++ objects from Python and overwriting virtual method with a Python implementation (requires usage of wrapper generator or manual work!)
  • Extensible handler for Python/C++ conversion of complex types, e.g. mapping of QVector<SomeObject> to/from a Python array
  • Setting of dynamic QObject properties via setProperty(), dynamic properties can be accessed for reading and writing like normal Python attributes (but creating a new property needs to be done with setProperty(), to distinguish from normal Python attributes)
  • Support for QtCore.Signal, QtCore.Slot and QtCore.Property, including the creation of a dynamic QMetaObject.

Features with wrapper generator

PythonQt offers the additional PythonQt_QtAll library which wraps the complete Qt API, including all C++ classes and all non-slots on QObject derived classes. This offers the following features:

  • Complete Qt API wrapped and accessible
  • The following modules are available as submodules of the PythonQt module:
    • QtCore
    • QtGui
    • QtNetwork
    • QtOpenGL (before Qt6)
    • QtSql
    • QtSvg
    • QtWebEngineWidgets
    • QtWebKit (when available)
    • QtXml
    • QtXmlPatterns (before Qt6)
    • QtMultimedia
    • QtQml
    • QtQuick
  • Any Qt class that has virtual methods can be easily derived from Python and the virtual methods can be reimplemented in Python
  • Polymorphic downcasting on QEvent, QGraphicsItem, QStyleOption, ...
  • Multiple inheritance support (e.g., QGraphicsTextItem is a QObject and a QGraphicsItem, PythonQt will handle this well)
  • QtQuick support is experimental and currently it is not possible to register new qml components from Python

Supported Versions

PythonQt supports:

  • Python 2 (>= Python 2.7)
  • Python 3 (>= Python 3.6)
  • Qt 4.x (Qt 4.7 and Qt 4.8 recommended) (not in the master branch, see below)
  • Qt 5.x (Tested with Qt 5.0, 5.3, 5.4, 5.6, 5.11, 5.12 and 5.15)
  • Qt 6.x (Tested with Qt 6.5 and 6.6) - support may not be complete, support for optional modules may be added as needed

The last working Qt4 version is available at svn branches/Qt4LastWorkingVersion or you can download the PythonQt 3.0 release. The current git master branch no longer supports Qt4, since we started to make use of some Qt5-only features.

Comparison with PySide

  • PythonQt is not as pythonic as PySide in many details (e.g. buffer protocol, pickling, translation support, ...) and it is mainly thought for embedding and intercommunication between Qt/Cpp and Python
  • PythonQt offers properties as Python attributes, while PySide offers them as setter/getter methods (e.g. QWidget.width is a property in PythonQt and a method in PySide, though in PySide6 in can also be made a property)
  • PythonQt currently does not support instanceof checks for Qt classes, except for the exact match and derived Python classes
  • QObject.emit to emit Qt signals from Python is not yet implemented but PythonQt allows to just emit a signal by calling it like a normal slot
  • Ownership handling of objects is not as complete as in PySide and PySide, especially in situations where the ownership is not clearly passed to C++ on the C++ API.
  • QStrings are always converted to unicode Python objects, QByteArray always stays a QByteArray and can be converted using QByteArray.data()
  • Qt methods that take an extra "bool* ok" parameter can be called passing PythonQt.BoolResult as parameter. In PySide, a tuple is returned instead.