Subclassing pg.ImageView failing in 0.12.2 and later

100 views
Skip to first unread message

Oli N

unread,
Jan 5, 2022, 12:17:30 AM1/5/22
to pyqt...@googlegroups.com
Hi all-

  I am trying to implement a way to interactively invert greyscale image colours.  I would like to do this by changing the way the colours are displayed rather than changing the original data (the original data can be somewhat complicated) - the best way of doing this that I could find is to extract the current ColorMap, apply its .reverse() method and re-apply that altered ColorMap.  This feature seems to have been introduced in PyQtGraph 0.12.2 and has been working fine in my code in a small test script based on the PyQtGraph example code in ImageView.py.  Essentially this:
inv_cmap = imw.ui.histogram.gradient.colorMap()
inv_cmap.reverse()
imw.setColorMap(inv_cmap)

Which does this nicely.
image.png

  I am subclassing pg.ImageView in my main code - the code I have been using works just fine in 0.12.1, but raises an odd exception in 0.12.2 and 0.12.3 (traceback included below.)  So I want the ColorMap.reverse() method but I am unable to use 0.12.2 or .3... :(
 

  Can anyone help me here? I would like to fix the subclassing if possible, and then use the .reverse() ColorMap method.  I am probably doing this wrong somewhere.
If this is important, I am variably using PySide6, PySide2 and maybe PyQt 5 on old Macs where I have trouble installing PySide.  These tracebacks were generated on PySide6, on Python 3.9.


Here is minimum code which reproduces the issues:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
from PySide6.QtWidgets import QWidget, QVBoxLayout

import pyqtgraph as pg
import numpy as np
import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.cw = QWidget(self)
        self.cw.setAutoFillBackground(True)
        self.setCentralWidget(self.cw)

        self.layout = QVBoxLayout()
        self.cw.setLayout(self.layout)

        self.ImgWidget = MyImageWidget(parent=self)
        self.layout.addWidget(self.ImgWidget)

        self.inv_btn = QPushButton('Invert Image')
        self.inv_btn.clicked.connect(self.ImgWidget.invert_image)
        self.layout.addWidget(self.inv_btn)

        self.resize(800, 800)
        self.show()


class MyImageWidget(pg.ImageView):
    def __init__(self, parent):
        super().__init__(parent, view=pg.PlotItem())

        # Clean up the interface
        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()

        self.plot = self.getView()
        self.plot.hideAxis('left')
        self.plot.hideAxis('bottom')
        self.plot.setMenuEnabled(False)

        self.inverted = False
        # 300x200 img random noise
        img = np.random.normal(size=(300, 200))
        self.setImage(img)

        self.def_cmap = self.ui.histogram.gradient.colorMap()
        self.inv_cmap = self.ui.histogram.gradient.colorMap()
        self.inv_cmap.reverse()

    def invert_image(self):
        self.inverted = not(self.inverted)
        if self.inverted:
            self.setColorMap(self.inv_cmap)
        else:
            self.setColorMap(self.def_cmap)


def main():
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()


in 0.12.2 and 0.12.3 the code fails on creation of the subclassed pg.ImageView - specifically the super statement.
Traceback (most recent call last):
  File "c:/Users/oli_n/pycode/examview/test-reverse.py", line 71, in <module>
    main()
  File "c:/Users/oli_n/pycode/examview/test-reverse.py", line 65, in main
    main = MainWindow()
  File "c:/Users/oli_n/pycode/examview/test-reverse.py", line 20, in __init__
    self.ImgWidget = MyImageWidget(parent=self)
  File "c:/Users/oli_n/pycode/examview/test-reverse.py", line 33, in __init__
    super().__init__(parent, view=pg.PlotItem())

  ...edit...

  File "c:\Users\oli_n\pycode\examview\.examview.env\lib\site-packages\pyqtgraph\graphicsItems\GradientEditorItem.py", line 642, in getGradient
    g.setStops([(x, QtGui.QColor(t.color)) for t,x in ticks])
AttributeError: 'PySide6.QtGui.QLinearGradient' object has no attribute 'setStops'
QPaintDevice: Cannot destroy paint device that is being painted


In 0.12.1 the subclassing seems to work OK, however an exception is thrown when trying the .reverse() ColorMap method - of course this method is not implemented in 0.12.1, only 0.12.2 and later.


Thanks!

Oli N

unread,
Jan 8, 2022, 10:00:40 AM1/8/22
to pyqtgraph
I have made some progress with this.

I upgraded from PySide 6.0.2 to 6.2.2.1 (the latest available in PyPi) the AttributeError: 'PySide6.QtGui.QLinearGradient' object has no attribute 'setStops' error disappeared, only to be replaced by another, well OK- the same one multiple times:
Traceback (most recent call last):
  File "c:\Users\oli_n\pycode\examview\.examview.env\lib\site-packages\pyqtgraph\graphicsItems\GraphicsObject.py", line 24, in itemChange
    self.parentChanged()
TypeError: native Qt signal is not callable


The same error (for a couple of different lines in the same file) is repeated multiple times (_many times_) but the code runs OK.
(yes - I receive a deprecation warning about this line sys.exit(app.exec_()) but of course that's OK)

I switched back to PySide 5 (5.15.2) and all runs well with pyqtgraph 0.12.3 with no errors/warnings.

So I am now only using PySide 5, which isn't a problem right now, but it sounds like support for this will be dropped by pyqtgraph soon.
__________________


OK- This seems to be related to what should have been fixed by PR #2132 (related to the PySIde bug https://bugreports.qt.io/browse/PYSIDE-1730 ).
Hopefully this makes it into the next pyqtgraph release.

Cheers-
 Oli

Oliver Nickalls

unread,
Jan 8, 2022, 9:58:57 PM1/8/22
to pyqt...@googlegroups.com
I mean PySide2 (version 5.15.2)...
--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/4d432044-bb2b-4cbc-85a0-5a2d744f4026n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages