Search code examples
c++qtsignalssignals-slotsqgraphicsitem

How to know which of the QGraphicsItems is being moved at the moment?


I have QGraphicsScene on which some custom QGraphicsItems are displayed. Those items are described in class MeasurePoint, which inherits from QGraphicsItem. They are also stored in QList, so each item has it's index. They are added to the scene like so:

void MeasureSpline::addNode(qreal xPos, qreal yPos, QGraphicsScene *scene)
{
    MeasurePoint *point = new MeasurePoint(xPos, yPos, points.size());
    points.append(point);
    point->setPoint(scene);
}

where points is:

QList<MeasurePoint*> points;

and each MeasurePoint is constructed like so:

MeasurePoint::MeasurePoint(qreal a, qreal b, int c)
{
    xPos = a;
    yPos = b;
    index = c;
    movable = false;
    selected = false;
}

and setPoint() is:

void MeasurePoint::setPoint(QGraphicsScene *scene)
{
    scene->addItem(this);
}

I have a method for setting items movable. If i use this method, the items become movable and i'm happy with the result. But my current goal is to know which of the items is being moved at the moment. Can it be done? How? Any help is appreciated.


Solution

  • First, make the QGraphicsItem make reacting on Position Changes like this:

    item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | 
    QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsScenePositionChanges);
    

    then you can reimplement the Change-Event and emit a Signal from there:

    QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value)
    {
    if (change == ItemPositionChange  && scene() || change == ItemScenePositionHasChanged)  // either during mouseMoveEvent or when Dropped again
    {
        emit itemMoved();  // connect to other SLOT and cast QObject::sender() or something here....
    }
        return QGraphicsItem::itemChange(change, value);
    }
    

    Edit:

    Untested Code for Receiving Method:

    void MyClass::onItemMoved()
    {
    
    MesurePoint* item = dynamic_cast<MesurePoint*>(QObject::sender());
    
    if (item != NULL)
     {
       int index = points.IndexOf(item);
     }
    }