How to get mouseover events for hole shapes in QGraphicsItem?

I have QGraphicsPathItemin Qt (using PySide bindings in Python) where inside there is a large rectangle and a smaller rectangle. Due to the default fill rule ( Qt.OddEvenFill), the inner rectangle is transparent. It effectively paints a shape with a hole.

Now I want to listen to mouse events, such as enter, leave, click, ... My simple approach to implementation hoverEnterEvent, .. of QGraphicsItemdoes not generate mouse events when moving through the hole, because the hole is still part of the element, even if it is not filled.

I want to have a derivative QGraphicsItemthat displays a custom shape, the outline of which is defined by QPainterPatheither one or more polygons and can have holes and when the mouse enters the hole, it is considered outside the shape.

An example of a form with a hole (when the mouse is in the inner rectangle, it should be considered as outside the form, and mouse exit events should be fired):

Shape with a hole

However, the solution should also work for arbitrary shapes with holes.

Sample code in PySide / Python 3.3

from PySide import QtCore, QtGui

class MyPathItem(QtGui.QGraphicsPathItem):

    def __init__(self):
        super().__init__()
        self.setAcceptHoverEvents(True)

    def hoverEnterEvent(self, event):
        print('inside')

    def hoverLeaveEvent(self, event):
        print('outside')

app = QtGui.QApplication([])

scene = QtGui.QGraphicsScene()
path = QtGui.QPainterPath()
path.addRect(0, 0, 100, 100)
path.addRect(25, 25, 50, 50)

item = MyPathItem()
item.setPath(path)
item.setBrush(QtGui.QBrush(QtCore.Qt.blue))

scene.addItem(item)

view = QtGui.QGraphicsView(scene)
view.resize(200, 200)
view.show()

app.exec_()
+4
source share
2 answers

, shape QGraphicsItem . , , . QGraphicsPathItem , . , , .

QGraphicsPathItem .

def shape(self):
    return self.path()
+2

, , (). - move/lineTo (, ). moveTo/lineTo:

from PySide import QtCore, QtGui

class MyPathItem(QtGui.QGraphicsPathItem):

    def __init__(self):
        QtGui.QGraphicsPathItem.__init__(self)
        self.setAcceptHoverEvents(True)

    def hoverEnterEvent(self, event):
        print('inside')

    def hoverLeaveEvent(self, event):
        print('outside')

app = QtGui.QApplication([])

scene = QtGui.QGraphicsScene()

path = QtGui.QPainterPath()
path.moveTo(0, 0)
path.lineTo(100, 0)
path.moveTo(0, 0)
path.lineTo(0, 100)
path.moveTo(100, 100)
path.lineTo(0, 100)
path.moveTo(100, 0)
path.lineTo(100, 100)

item = MyPathItem()
pen = QtGui.QPen()
pen.setWidth(25)
pen.setColor(QtCore.Qt.blue)
item.setPen(pen)
item.setPath(path)

scene.addItem(item)

view = QtGui.QGraphicsView(scene)
view.resize(200, 200)
view.show()

app.exec_()
0

All Articles