Qt mouse event propagation with scene items

走远了吗. 提交于 2019-12-11 18:57:40

问题


When QGraphicsScene item is behind it's child Item, I wish for mouse grabber to check item behind, and then grab topmost item if the first is not grabbed.

SAMPLE CODE :

from PySide.QtCore import *
from PySide.QtGui import *

class View(QGraphicsView):
    pass
class Scene(QGraphicsScene):
    pass

class ChildCircle(QGraphicsEllipseItem):
    def __init__(self, parent):
        super(ChildCircle, self).__init__()
        self.setRect(QRect(-20,-20,70,70))
        self.setParentItem( parent )

    def mousePressEvent(self, event):
        print "Circle is Pressed", event.pos()

class ParentRectangle(QGraphicsRectItem):
    def __init__(self, scene):
        super(ParentRectangle, self).__init__()
        self.scene = scene
        self.setRect(QRect(0,0,20,20))
        self.scene.addItem(self)

        circle = ChildCircle(self)

    def mousePressEvent(self, event):
        print "Rectangle PRESS", event.pos()


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.s = Scene()
        self.s.setSceneRect(-200,-100,300,300,)

        self.v = View(self.s)
        self.v.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setCentralWidget(self.v)

        ParentRectangle(self.s)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.resize(300, 200)
    window.show()
    sys.exit(app.exec_())

回答1:


I am not sure I understand your question. The Qt's documentation clearly says the following about mousePressEvent method:

The mouse press event decides which item should become the mouse grabber. If you do reimplement this function, event will by default be accepted (see QEvent::accept()), and this item is then the mouse grabber. This allows the item to receive future move, release and doubleclick events. If you call QEvent::ignore() on event, this item will lose the mouse grab, and event will propagate to any topmost item beneath.

All you have to do it's to decide whether to call QEvent::ignore method or not. So, for example, if the circle object does always ignore mouse press event, the rectangle object will always be the mouse grabber (if you clicked on rectangle). In this code the mouse grabber is item you have clicked.

class ChildCircle(QGraphicsEllipseItem):
    def __init__(self, parent=None):
        super(ChildCircle, self).__init__(parent)
        self.setRect(QRect(-20,-20,70,70))
        self.setFlags(QGraphicsItem.ItemIsMovable)

    def mousePressEvent(self, event):
        # Ugly way to know there are items except self
        if len(self.scene().items(event.scenePos())) > 1:
            # Propogate the event to the parent
            event.ignore()

class ParentRectangle(QGraphicsRectItem):
    def __init__(self, scene, parent=None):
        super(ParentRectangle, self).__init__(parent)
        self.scene = scene
        self.setRect(QRect(0,0,20,20))
        self.scene.addItem(self)
        circle = ChildCircle(self)
        self.setFlags(QGraphicsItem.ItemIsMovable)

    def mousePressEvent(self, event):
        pass


来源:https://stackoverflow.com/questions/16772227/qt-mouse-event-propagation-with-scene-items

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!