如何避免鼠标事件被QGraphicsView吃掉

How to avoid mouse events being eaten by QGraphicsView

我希望鼠标事件到达适当的 QGraphicsItem,但它们只到达 QGraphicsView。

我已将我的代码减少到 41 行,注释掉了事件处理程序但无济于事。如果 QGraphicsView 有处理程序,它要么由 QGraphicsView 处理,要么如果没有,则根本不会被捕获。

我确定我遗漏了一些明显的东西,但我看不到。

from PyQt5.QtWidgets import *

class MyFrame(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setScene(QGraphicsScene())
        self.scene().addItem(Group())

    def mouseReleaseEvent(self, event):
        print('in QGraphicsView')
        return QGraphicsView.mouseReleaseEvent(self, event)

class Group(QGraphicsItemGroup):
    def __init__(self, parent=None):
        super().__init__()

        item = MyEllipse(0, 0, 20, 20)
        self.addToGroup(item)

    def mouseReleaseEvent(self, event):
        print('in QGraphicsItemGroup')
        return QGraphicsItemGroup.mouseReleaseEvent(self, event)

class MyEllipse(QGraphicsEllipseItem):
    def mouseReleaseEvent(self, event):
        print('in QGraphicsEllipseItem')
        return QGraphicsEllipseItem.mouseReleaseEvent(self, event)

if __name__ == '__main__':
    app = QApplication([])
    f = MyFrame()
    f.show()
    app.exec_()

mouseReleaseEvent 当且仅当 mousePressEvent 处理的事件被接受时才会调用,因此使用以下代码事件将到达 QGraphicsItemGroup:

class Group(QGraphicsItemGroup):
    def __init__(self, parent=None):
        super().__init__()

        item = MyEllipse(0, 0, 20, 20)
        self.addToGroup(item)

    def mousePressEvent(self, event):
        QGraphicsItemGroup.mousePressEvent(self, event)
        event.accept()

    def mouseReleaseEvent(self, event):
        print('in QGraphicsItemGroup')
        QGraphicsItemGroup.mouseReleaseEvent(self, event)

但正如 @ekhumoro 指出的那样,QGraphicsItemGroup 充当单个元素,因此事件不会传输到它们处理的项目。

如果要检测何时按下项目可以使用以下方法:

class Group(QGraphicsItemGroup):
    def __init__(self, parent=None):
        super().__init__()

        self._item = MyEllipse(0, 0, 20, 20)
        self.addToGroup(self._item)

    def mousePressEvent(self, event):
        QGraphicsItemGroup.mousePressEvent(self, event)
        event.accept()

    def mouseReleaseEvent(self, event):
        print('in QGraphicsItemGroup')
        if self._item.mapToParent(self._item.boundingRect()).containsPoint(event.pos(), Qt.OddEvenFill):
            print("_item")
        QGraphicsItemGroup.mouseReleaseEvent(self, event)