It's out now! Get the PyQt6 Edition or PySide6 Edition
I'm currently in the process of updating my book Creating GUI Applications with Python and Qt for the Qt6 releases of Qt. While these new versions are largely backwards compatible with Qt5 there are a number of significant differences which will cause issues when migrating from PyQt5 to PyQt6 or PySide2 to PySide6.
We now also have migration guides for moving from PyQt5 to PyQt6 or PySide2 to PySide6.
QResource Support Removed in PyQt6
One major difference only applies to PyQt6: Riverbank Computing have removed QResource support from PyQt6. If you have no idea what that is, don't worry, you're not alone. The QResource System is used to manage application resources — think images, icons, stylesheets — from within Qt Designer. By compiling these resources into Python code they could be used directly from within the application without needing to worry about paths.
If this sounds pretty useful it is, but it's not commonly used: probably because managing the assets in Qt Designer isn't particularly friendly.
Key Migration Differences Between Qt5 and Qt6
Some other thoughts from the migration —
- Enum namespaces changed in PyQt6: PyQt6 is less directly source-compatible with PyQt5 than PySide6. In PyQt6 the namespaces have been moved under Python Enums so e.g.
Qt.DisplayRoleis now underQt.ItemDataRole.DisplayRole. The same structure exists now in PySide6, but the old locations are retained, so it's backwards compatibleQt.ItemDataRole.BackgroundRole == Qt.BackgroundRole. I'm 50/50 on whether to use the new style in the PySide6 book — thoughts? - QAction moved from QtWidgets to QtGui in PyQt6 and PySide6:
QActionis now inQtGuinotQtWidgets. This always caught me out (since it's not a widget) so I think it's a good change. But it's hard to auto-migrate. - Pixmap returns a copy in PyQt6 and PySide6: Retrieving a pixmap now seems to return a copy: if you get a label's pixmap and draw on it, it doesn't affect the widget. Required a rewrite of the custom widget code. May be missing something here, early days.
- QMouseEvent position methods changed in PyQt6:
QMouseEventnow doesn't have.x()or.y()which is odd. You need to get a position viaQMouseEvent.position()instead.
Deprecated QEnterEvent Functions in PySide6.1
In addition, in PySide6.1, the following QEnterEvent functions are all deprecated:
QEnterEvent.globalPos()
QEnterEvent.globalX()
QEnterEvent.globalY()
QEnterEvent.localPos()
QEnterEvent.pos()
QEnterEvent.screenPos()
QEnterEvent.windowPos()
QEnterEvent.x()
QEnterEvent.y()
It is still early days, and it's quite possible I'll find more incompatibilities as I dig further. The next version of the book should be out, at least in an "early access" form, by next week.
For an up to date migration guide see PyQt5 to PyQt6 or PySide2 to PySide6.
Packaging Python Applications with PyInstaller by Martin Fitzpatrick
This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.