如何将 QGraphicsItemGroup 鼠标事件传播到子元素?

问题描述 投票:0回答:1

是否可以将

QGraphicsItemGroup
鼠标事件传播到子添加的项目?

setHandlesChildEvents(false) 已弃用,我不想使用它。

我尝试过这个,但没有成功:

class MoveItemBase : public QObject, public QGraphicsItem;

bool sceneEvent(QEvent* event) override
{
    if (event->type() == QEvent::GraphicsSceneMouseDoubleClick) {
        propagateSceneEvent(event);
        return true;
    }

    return QGraphicsItemGroup::sceneEvent(event);
}
void propagateSceneEvent(QEvent* event)
{
    for (QGraphicsItem* child : childItems()) {
        MoveItemBase* widget = static_cast<MoveItemBase*>(child);  
        QCoreApplication::sendEvent(widget, event);
    }
}
qt qgraphicsscene qgraphicsitem qt6 qgraphicsitemgroup
1个回答
2
投票

据我所知和发现,没有直接替代 setHandlesChildEvents

但是,我确实在 Qt Center Forum 上的这个线程中找到了解决方法:setHandlesChildEvents() 已过时?,其中建议使用 QGraphicsItem::installSceneEventFilter,其中表示:

在filterItem上安装该项目的事件过滤器,导致该项目的所有事件首先通过filterItem的sceneEventFilter()函数。

...

一个项目只能过滤同一场景中其他项目的事件。

根据这些发现,我做了一个通用示例来实现:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsItem>

//class of the item used as an event filter for other graphic items
class FilterItem :  public QGraphicsLineItem
{
public:
    FilterItem (QGraphicsItem *parent = nullptr)
    {}

protected:
    bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
    {
        //check event
        if(event->type() == QEvent::GraphicsSceneMouseDoubleClick)
        {
            //handle it as you wish
            qDebug()<<"Handling child graphics item event here";
            return true;
        }

        return QGraphicsItem::sceneEventFilter(watched,event);
    }
};

int main(int argc,char*argv[])
{
    QApplication a(argc, argv);

    QGraphicsView v;
    QGraphicsScene scene;
    FilterItem *filterItem = new FilterItem;
    QGraphicsRectItem *targetItem = scene.addRect(QRect(10, 10, 50, 50));

    //the filter item has to be added to the same scene
    scene.addItem(filterItem);
    //install it on the targeted item
    targetItem->installSceneEventFilter(filterItem);

    v.setScene(&scene);
    v.show();

    return a.exec();
}
© www.soinside.com 2019 - 2024. All rights reserved.