pythonpyqtpyqt5qgraphicspixmapitem

Painting QGraphicsPixmapItem border on hover


I'm trying to create my own QGraphicsPixmapItem where I can active on hover mode and I want to paint a black border when I hover over the rect of the item, and go back to normal when I leave the rect space.

I started this code, but don't know what to do next. Also wanted to do a paintEvent, but QGraphicsPixmapItems doesn't have that. So am even more confused as don't think the paint method would be the same.

class PixmapItem(QGraphicsPixmapItem):
    def __init__(self, pixmap, rect, parent=None):
        super().__init__(parent)
        self.pixmap = pixmap
        self.setPixmap(self.pixmap)
        self.rect = rect
        self.setAcceptHoverEvents(True)

    def hoverEnterEvent(self, *args, **kwargs):
        pass

I could make the hover print 'hello' but can't do anything else, even with some examples, because those are with paintEvent and other type of items.

I would like to maintain the type of item if possible and paint the border as i said. But also don't know if it would be a better approach that's also simple.


Solution

  • The QGraphicsItem do not have the paintEvent method but the paint() method:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class PixmapItem(QtWidgets.QGraphicsPixmapItem):
        def __init__(self, pixmap, parent=None):
            super().__init__(pixmap, parent)
            self.setAcceptHoverEvents(True)
            self._is_hovered = False
    
        def hoverEnterEvent(self, event):
            self._is_hovered = True
            self.update()
            super().hoverEnterEvent(event)
    
        def hoverLeaveEvent(self, event):
            self._is_hovered = False
            self.update()
            super().hoverLeaveEvent(event)
    
        def paint(self, painter, option, widget=None):
            super().paint(painter, option, widget)
            if self._is_hovered:
                painter.save()
                pen = QtGui.QPen(QtGui.QColor("black"))
                pen.setWidth(4)
                painter.setPen(pen)
                painter.drawRect(self.boundingRect())
                painter.restore()
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        scene = QtWidgets.QGraphicsScene()
        view = QtWidgets.QGraphicsView(scene)
        item = PixmapItem(QtGui.QPixmap("image.png"))
        scene.addItem(item)
        view.resize(640, 480)
        view.show()
        sys.exit(app.exec_())
    

    Update:

    def paint(self, painter, option, widget=None):
        super().paint(painter, option, widget)
        if self._is_hovered:
            painter.save()
            pen = QtGui.QPen(QtGui.QColor("black"))
            pen.setWidth(4)
            painter.setPen(pen)
            r = self.boundingRect()
            r.adjust(0, 0, -pen.width()/2, -pen.width()/2)
            painter.drawRect(r)
            painter.restore()