是否可以将
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);
}
}
据我所知和发现,没有直接替代 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();
}