Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Updating QGraphicsEffect for QGraphicsSvgItem



  • Hi. I have a class derived from QGraphicsSvgItem, which I'd like to be able to apply graphical effects to during selection of these items in my scene.

    With QGraphicsItems, I've been able to re-implement the 'paint' method, and do something during 'isSelected()' - such as changing pen or brush colours. No big deal...

    With QGraphicsSvgItem, I've gotten stuck in understanding how to re-implement the paint method (I haven't been able to get my graphic to display at all once I've added this method to my class). My question is: what code do I need to add after re-implementing 'paint' in order to get the graphic to display? Am I maybe trying to go about this the wrong way?

    Here's some example code:

    from PyQt5.QtWidgets import *
    from PyQt5.QtSvg import *
    from PyQt5.QtCore import *
    
    
    class MySVG(QGraphicsSvgItem):
        def __init__(self, icon):
            super().__init__(icon)
    
            self.setFlags(QGraphicsSvgItem.ItemIsSelectable | QGraphicsSvgItem.ItemSendsGeometryChanges)
    
        # when I uncomment the code below, svg image doesn't show. I'm confused about what I need to write here...
    
        # def paint(self, painter, option, widget=None):
        #
        #     # I want to set a graphics colorize effect when item is selected, and disable the effect when deselected
        #     if self.isSelected():
        #         self._effect = QGraphicsColorizeEffect()
        #         self._effect.setColor(Qt.red)
        #         self._effect.setStrength(.5)
        #         self.setGraphicsEffect(self._effect)
        #
        #     else:
        #         pass
        #         #self.setGraphicsEffect(0)
    
    svg_icon_path = 'E:\\dev\\qt_aStar\\SVG\\input.svg'
    
    app = QApplication([])
    scene = QGraphicsScene()
    view = QGraphicsView(scene)
    
    svg_item = MySVG(svg_icon_path)
    scene.addItem(svg_item)
    
    view.show()
    app.exec_()
    
    
    
    

    Any advice would be much appreciated,
    Thanks!

    Stu


  • Banned

    @S-Tozer said in Updating QGraphicsEffect for QGraphicsSvgItem:

    paint

    You do not seem to be passing this on to the parent objects method so you intercept and stop its normal processing



  • This post is deleted!


  • Thanks Denni. I'm still confused about what I need to be passing to what, unfortunately (I'm quite new to QGraphics scenes/views/and items). I've edited my code example above, simplifying it and making it a more complete (runnable) example.


  • Banned

    Okay I took your MUC (Minimal Usable Code) or MRE (Minimal Reproducible Example) and did a little mucking around ;-) and made it more pythonic/pyqt-ish and fixed your bug so here is the re-rendered version

    from PyQt5.QtWidgets import *
    from PyQt5.QtSvg import *
    from PyQt5.QtCore import *
    
    
    class MySVG(QGraphicsSvgItem):
        def __init__(self, icon):
            QGraphicsSvgItem.__init__(self, icon)
    
            self.setFlags(QGraphicsSvgItem.ItemIsSelectable | QGraphicsSvgItem.ItemSendsGeometryChanges)
    
        # when I uncomment the code below, svg image does not show. I'm confused about what I need to write here...
    
        def paint(self, painter, option, widget=None):
         # I want to set a graphics colorize effect when item is selected, and disable the effect when deselected
            if self.isSelected():
                self._effect = QGraphicsColorizeEffect()
                self._effect.setColor(Qt.red)
                self._effect.setStrength(.5)
                self.setGraphicsEffect(self._effect)
            else:
                pass
                #self.setGraphicsEffect(0)
            QGraphicsSvgItem.paint(self, painter, option, widget)
    
    class MainWindow(QGraphicsView):
        def __init__(self):
            QGraphicsView.__init__(self)
            SvgIconPath = 'E:/dev/qt_aStar/SVG/input.svg'
    
            self.SvgItem = MySVG(SvgIconPath)
    
            self.MyScene = QGraphicsScene()
            self.MyScene.addItem(self.SvgItem)
            
            self.setScene(self.MyScene)
    
    if __name__ == "__main__":
        MainEventThred = QApplication([])
    
        MainApp = MainWindow()
        MainApp.show()
    
     # Note this is the PyQt5 version of this line yours was PyQt4
        MainEventThred.exec()
    

    Now I am not sure what it was supposed to do with the code segment you put into place but with or with out paint function the "svg" display



  • @Denni-0 said in Updating QGraphicsEffect for QGraphicsSvgItem:

    Denni, that's great! Thanks so much. :):) I had tried -

     def paint(self, painter, option, widget=None):
        self.paint(self, painter, option, widget)
    

    Which looked kindof ridiculous (I was just calling the same method on itself, whereas I had to use the actual parent object as you tried to explain to me in previous post).

    Only one thing - my code for disabling the graphicsEffect when my item is deselected doesn't appear to work -

    self.setGraphicsEffect(0)
    

    I'm sure this is no big deal and I will dig around a bit for the answer.

    Thanks again for your time and help on this -

    Stu


  • Banned

    @S-Tozer well if you gave more details -- like where are you trying to set that value and which object is that self. referring to -- I might have been able to point you in the right direction?



  • Thanks and apologies.

    I was referring to setting the graphics effect in the 'paint' method on selection of the item, or disabling it once the item is deselected.

    I ended up going with, in the constructor:

            self._colourise_effect = QGraphicsColorizeEffect()
            self.setGraphicsEffect(self._colourise_effect)
            self._colourise_effect.setEnabled(False)
    

    and in the 'paint' method:

            if self.isSelected():
                self._colourise_effect.setEnabled(True)
            else:
                self._colourise_effect.setEnabled(False)
    

    'self.setGraphicsEffect(0)' or 'self.setGraphicsEffect(None) was not working... (although I had seen this in other code snippets)

    Cheers!


Log in to reply