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. 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 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:
- 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
- Python 2 (>= Python 2.6)
- Python 3 (>= Python 3.3)
- Qt 4.x (Qt 4.7 and Qt 4.8 recommended)
- Qt 5.x (Tested with Qt 5.0, 5.3, 5.4 and 5.6)
The last working Qt4 version is available at svn branches/Qt4LastWorkingVersion or you can download the PythonQt 3.0 release. The current svn trunk 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)
- 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.