C++ QGraphicsItem中的itemChanged()用于许多不同的项目

C++ QGraphicsItem中的itemChanged()用于许多不同的项目,c++,qt,qgraphicsitem,C++,Qt,Qgraphicsitem,我有一个应用程序,在qgraphiscene中包含许多不同的项目。 这些项目可以是矩形、椭圆、像素贴图,或者从QGraphicsItem继承的任何东西。 用户可以在这些项目周围移动。(设置了每个QGraphicsItem::ItemIsMovable标志) 应用程序需要获取一个事件(回调、信号或其他)来获取新位置 如何一次性为所有这些可能的项重载itemChanged()方法?。我希望避免子类化每个可能的项(即为qgraphicselipseitem创建派生类,为QGraphicsPixmapI

我有一个应用程序,在
qgraphiscene
中包含许多不同的项目。 这些项目可以是矩形、椭圆、像素贴图,或者从
QGraphicsItem
继承的任何东西。 用户可以在这些项目周围移动。(设置了每个
QGraphicsItem::ItemIsMovable
标志)

应用程序需要获取一个事件(回调、信号或其他)来获取新位置

如何一次性为所有这些可能的项重载
itemChanged()
方法?。我希望避免子类化每个可能的项(即为
qgraphicselipseitem
创建派生类,为
QGraphicsPixmapItem
创建其他派生类,以及为任何未来的项创建子类…)

我希望能够告诉您:每当一个
QGraphicsItem
(或它派生的任何东西)发生更改时,调用我的函数:

 my_item_changed(QGraphicItem* the_change_item,...).
然后能够添加不同的项目类型,而无需再担心


有什么提示吗?

您可以在QGraphics站点上安装事件筛选器。特别是,您需要使用此函数:-

void QGraphicsItem::installSceneEventFilter(QGraphicsItem * filterItem);
bool QGraphicsItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event)
{
    if(event->type() == QEvent::GraphicsSceneMove)
    {
        emit my_item_changed(watched); // signal that the item was moved
    }

    return false; // pass the event to the original target item
}
正如Qt文档所述,下面是一个使用示例:-

QGraphicsScene scene;
QGraphicsEllipseItem *ellipse = scene.addEllipse(QRectF(-10, -10, 20, 20));
QGraphicsLineItem *line = scene.addLine(QLineF(-10, -10, 20, 20));

line->installSceneEventFilter(ellipse);
// line's events are filtered by ellipse's sceneEventFilter() function.

ellipse->installSceneEventFilter(line);
// ellipse's events are filtered by line's sceneEventFilter() function.
基于此,创建一个从QGraphicsItem派生的类,该类可以首先接收事件。对于添加到场景中的每个项目,请调用installSceneEventFilter:-

mySceneEventItem.installSceneEventFilter(pGraphicsItem);
接下来,eventFilter对象将覆盖该函数:-

void QGraphicsItem::installSceneEventFilter(QGraphicsItem * filterItem);
bool QGraphicsItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event)
{
    if(event->type() == QEvent::GraphicsSceneMove)
    {
        emit my_item_changed(watched); // signal that the item was moved
    }

    return false; // pass the event to the original target item
}
这允许您检查事件并处理您感兴趣的事件。如果从sceneEventFilter返回false,则在处理该事件后,该事件将传递到原始对象;返回true将阻止事件传递