Qt鼠标事件传播与场景项目 [英] Qt mouse event propagation with scene items

查看:48
本文介绍了Qt鼠标事件传播与场景项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当 QGraphicsScene 项目在它的子项目后面时,我希望鼠标抓取器检查后面的项目,如果第一个没有被抓取,然后抓取最上面的项目.

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.

示例代码:

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_())

推荐答案

我不确定我是否理解您的问题.Qt 的文档清楚地说明了关于 mousePressEvent 方法的以下内容:

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

鼠标按下事件决定哪个项目应该成为鼠标抓取器.如果你重新实现这个函数,event 将默认为接受(见QEvent::accept()),然后这个item就是鼠标抓取器.这允许项目接收未来的移动、发布和双击事件.如果您在事件上调用 QEvent::ignore(),则此项将失去鼠标抓取,并且事件将传播到任何最顶层的项目下面.

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.

您所要做的就是决定是否调用QEvent::ignore 方法.因此,例如,如果圆形对象始终忽略鼠标按下事件,则矩形对象将始终是鼠标抓取器(如果您单击矩形).在此代码中,鼠标抓取器是您单击的项目.

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

这篇关于Qt鼠标事件传播与场景项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆