Qt.py icon indicating copy to clipboard operation
Qt.py copied to clipboard

Additional PySide2 caveats

Open mottosso opened this issue 8 years ago • 12 comments

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.

mottosso avatar Jun 21 '16 13:06 mottosso

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

mottosso avatar Jun 25 '16 15:06 mottosso

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.

fredrikaverpil avatar Jun 25 '16 22:06 fredrikaverpil

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()?

fredrikaverpil avatar Jun 25 '16 22:06 fredrikaverpil

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.

mottosso avatar Jun 26 '16 08:06 mottosso

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 or QtQuick)
  • QApplication extends QGuiApplication 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.

fredrikaverpil avatar Jun 26 '16 11:06 fredrikaverpil

With tests in place, it's time to get this baby off the floor and into the oven as well. CAVEATS.md style!

mottosso avatar Jun 29 '16 21:06 mottosso

...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.

zhihaoadsk avatar Jul 27 '16 23:07 zhihaoadsk

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!

hdd avatar Aug 08 '16 14:08 hdd

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!

mottosso avatar Aug 08 '16 17:08 mottosso

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

mottosso avatar Aug 08 '16 17:08 mottosso

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).

hdd avatar Aug 09 '16 08:08 hdd

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.

hdd avatar Aug 09 '16 13:08 hdd