如何避免鼠标事件被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)
我希望鼠标事件到达适当的 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)