This is a question for Martin Fitzpatrick specifically. Will there ever be a book about PyQt6 and/or PySide6? I want to port my code to version 6, but I have a lot of issues. So I am wondering whether there are any plans in the air. Even just a porting guide from PyQt5/PySide2 to PyQt6/PySide6 would be a wonderful thing.
Short answer: yes! I've started work on it this week, just converting over the source code for the examples + familiarising myself with the changes (some things have been removed, e.g. QResources from PyQt6 so those sections will need to be rewritten).
It's early days, but I'll get porting guide out first + there is another update to the PyQt5 book on the way.
Getting there, about 90% of the code is migrated for both PyQt6 & PySide6. Then I have a list of changes to make to the book/conditional sections for the new libraries + we're good to go for a initial release. The v6 versions will be available to anyone who's bought an earlier edition.
All the code for the different versions is auto-generated from the PyQt5 source. PyQt5 to PySide2 requires replacing the imports and signal/slot names + some manual handwritten replacements for the UI loader. The same process has been done for v6 and that's given me some insight into where the incompatibilities are.
Some first thoughts from the migration --
- PyQt6 is less directly source-compatible with PyQt6 than PySide6. In PyQt6 the namespaces have been moved under Python Enums so e.g.
Qt.DisplayRoleis now under
Qt.ItemDataRole.DisplayRole. The same structure exists now in PySide6, but the old locations are retained, so it's backwards compatible
Qt.ItemDataRole.BackgroundRole == Qt.BackgroundRole. I'm 50/50 on whether to use the new style in the PySide6 book -- thoughts?
- (PyQt6 & PySIde6)
QActionis now in
QtWidgets. 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.
- (PyQt6 & PySIde6) Retrieving a pixmap now seems to return a copy: if you get a labels 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.
QMouseEventnow doesn't have
.y()which is odd. You need to get a position via
The matplotlib examples won't work until Qt6 is supported there and there is (as yet) no support for packaging PyQt6/PySide6 in PyInstaller or fbs. I'll remove this part of the book until it becomes available.
Should be out, at least in an "early access" form, by next week.
The same structure exists now in PySide6, but the old locations are retained, so it’s backwards compatible
Qt.ItemDataRole.BackgroundRole == Qt.BackgroundRole. I’m 50/50 on whether to use the new style in the PySide6 book – thoughts?
I think it'd be best to use the new style, because someday in the future that backwards compatibility might be removed. Just my 2 cents.
Yesterday I noticed that while PyQt6 & PySide2 Enum types are identical between PyQt6 & PySide6, flag types have different names. So
Qt.GlobalColor.white (enum) is the same in both. But alignment flags are in
Qt.Alignment.AlignLeft in PyQt6 and
Qt.AlignmentFlag.AlignLeft in PySide6.
For this update I've kept PySide6 using the short-form names, since this matches what is used in the PySide6 documentation. Will keep an eye on how things change in future, it's a bit painful to maintain the two different styles.
In PySide6.1, the functions:
QEnterEvent.globalPos() QEnterEvent.globalX() QEnterEvent.globalY() QEnterEvent.localPos() QEnterEvent.pos() QEnterEvent.QEnterEvent.screenPos() QEnterEvent.QEnterEvent.windowPos() QEnterEvent.QEnterEvent.x() QEnterEvent.QEnterEvent.y()
- all are deprecated.
The matplotlib examples won’t work until Qt6 is supported there
The experimental branch with Qt6 support which is mentioned in the book, ch. 36 Plotting with Matplotlib, PDF p. 582, has recently been merged into Matplotlib's
master branch. This should be in Matplotlib v3.5, apparently due tomorrow August 18, and then soon after in PyPI, so the experimental branch will no longer be needed.
To support developers in [[ countryRegion ]] I give a [[ localizedDiscount[couponCode] ]]% discount with the code [[ couponCode ]] — Enjoy!
For [[ activeDiscount.description ]] I'm giving a [[ activeDiscount.discount ]]% discount with the code [[ couponCode ]] — Enjoy!