Qt.py
Qt.py copied to clipboard
Additional PySide2 caveats
Found some more cross-development tips here:
- https://github.com/PySide/pyside2/wiki/My_Practice_:_Porting_python_scripts_to_PySide2
Pasting them here in case they disappear. Will need formatting.
QHBoxLayout QVBoxLayout
Background:
Qt4 (PySide): QLayout::setAlignment(Qt::Alignment alignment)
http://doc.qt.io/qt-4.8/qlayout.html#setAlignment-2
Qt5 (PySide2): removed the above method
http://doc.qt.io/qt-5/qlayout.html#setAlignment
To upgrade to PySIde2, we have to make the following changes for
QHBoxLayout::setAlignment(Qt::Alignment alignment)
QVBoxLayout::setAlignment(Qt::Alignment alignment)
Qt4 (PySide):
layout = QHBoxLayout()
layout.setAlignment(Qt.AlignLeft)
Qt5(PySide2) : --solution
layout = QHBoxLayout()
QLayoutItem.setAlignment(layout, Qt.AlignLeft)
QHeaderView
Qt4 (PySide): http://doc.qt.io/qt-4.8/qheaderview.html
void setResizeMode(ResizeMode mode);
void setResizeMode(int logicalIndex, ResizeMode mode);
Qt5(PySide2) : http://doc.qt.io/qt-5/qheaderview.html
void setSectionResizeMode(ResizeMode mode);
void setSectionResizeMode(int logicalIndex, ResizeMode mode);
Solution:
pysideVersion = '-1'
try:
import PySide
pysideVersion = PySide.__version__
except ImportError:
import PySide2
pysideVersion = PySide2.__version__
if pysideVersion == '1.2.0':
treeUI.header().setResizeMode(QHeaderView.Fixed)
treeUI.header().setResizeMode(TREE_COLUMN_NAME, QHeaderView.Interactive)
treeUI.header().setResizeMode(TREE_COLUMN_WEIGHT, QHeaderView.Stretch)
else:
treeUI.header().setSectionResizeMode(QHeaderView.Fixed)
treeUI.header().setSectionResizeMode(TREE_COLUMN_NAME, QHeaderView.Interactive)
treeUI.header().setSectionResizeMode(TREE_COLUMN_WEIGHT, QHeaderView.Stretch)
QApplication.palette()
Background:
Qt4:
QPalette QApplication::palette()
http://doc.qt.io/qt-4.8/qapplication.html#palette
Qt5:
QPalette QGuiApplication::palette()
http://doc.qt.io/qt-5/qguiapplication.html#palette
Solution:
PySide(Qt4): palette = QApplication.palette()
PySide2 (Qt5): palette = QGuiApplication.palette()
Another workaround:
palette = self.palette() # self is widget
# as you could also find palette() within QWidget class http://doc.qt.io/qt-5/qwidget.html
# it works for both Qt4 and Qt5.
Might be worth adding a link to the official wiki on the subject, to ackowledge that we've taken it into account. Should we duplicate the contents here a well? For competeness, and to protect against broken links?
- https://wiki.qt.io/Differences_Between_PySide_and_PyQt
It also mentions two more projects that overlaps with what Qt.py does.
- https://github.com/epage/PythonUtils/blob/master/util/qt_compat.py
- https://github.com/ros-visualization/python_qt_binding
Might be worth adding a link to the official wiki on the subject
👍
Should we duplicate the contents here a well?
I'm all for completeness. I've come along too many broken links in my day... as long as it doesn't get too tedious to maintain.
Just a quick question on QGuiApplications.palette()
... I didn't have to do this here. That code works in PyQt4 and in PyQt5 (with both Python 2/3).
~~Does that mean that PySide2 and PyQt5 are backwards compatible for palette()
?~~ I mean... does that mean you could just as well call QtWidgets.QApplication.palette()
instead of calling QtGui.QGuiApplication.palette()
?
Hm, I'm not sure what that's about. I'd expect QApplication to work fine as well. Pinging the author, @zhihaoadsk. Would it be possible to shed some light on this?
What this also tells me is that we need tests for these. Something to confirm they actually are a problem.
For Qt5:
-
QCoreApplication
is the base class -
QGuiApplication
extends the base class with functionality related to handling windows and GUI stuff (non-widget related, e.g.QtOpenGL
orQtQuick
) -
QApplication
extendsQGuiApplication
with functionality related to handling widgets
Source here.
Since QApplication.palette()
exists and works in both Qt4 and Qt5, I don't see any need to create a remap or similar here. For QGuiApplication
, which only exists in Qt5, I guess the user must take this into consideration and do something alltogether different for Qt4 or not use this for Qt4.
With tests in place, it's time to get this baby off the floor and into the oven as well. CAVEATS.md style!
...QGuiApplications.palette()... Thanks fredrikaverpil! Glad that it works now. skip the item please:) Background: back then(Qt5.5) it doesn't work when I wrote the wiki. Probably Qt5.6 updated something.
HI Marcus, thanks for this.
I'm now hitting the issue with HeaderView, and wondering.... isn't there a way to provide (read wrap) either setResizeMode to setSectionResizeMode or the other way round ?
having to fill up already pretty complex code with try/except if/else is something I would be happily avoiding :)
Thanks!
Hey @hdd, yes, definitely. This is an interesting area of research and development. The way I've pictured it is by offering subclasses via QtWidgets and such that act as their real counterparts, but implement the missing/remapped functionality. But I'm open to alternatives. The end goal should be what you expect.
It should be enough to handle a majority of compatibility issues and also work with non-Qt.py bindings as well.
Pull-requests are welcome!
This will also require a push into expanding tests to cover Qt 5 bindings as well, because at the moment they only cover PyQt4 and PySide differences.
I had an idea for how to achive this via Docker that I think will work well, both for testing via Travis and locally, without having to install every binding on a single OS.
I'll type up an issue about it. Edit: #93
Happy to help on this.
let me know which is the issue number so I can create a pull request against master. I like the idea of providing both implementations, the only addition I would make is to provide notice to the users (warnings, so they can disabled) that the call they are making is for another version (if it's the case).
started looking into this https://github.com/EfestoLab/Qt.py/tree/bridge-header-resize-calls started with a naive approach, let see whether is enough.