Search code examples
qtmousemouseeventqgraphicsviewqgraphicsitem

How to quantize the position of multiple QGraphicsItems while dragging the mouse in a QGraphicsView?


Hello and thanks for reading. I am having trouble correctly quantizing the position of multiple QGraphicsItems while dragging the mouse in a QGraphicsView. The system I have setup is correctly quantizing a QGraphicsItem if only drag one at a time, however if I have multiple selected and drag them, only the primary item(the one directly under the mouse) is quantized, the rest have their positions set continuously. I would very much appreciate any help with this. The relevant code follows:

This is in a class called MutaEvent which inherits from QGraphicsRectItem. I have redefined the mouseMoveEvent() and setPos() functions:

void MutaEvent::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
{
    QGraphicsRectItem::mouseMoveEvent(event);
    setPos(pos());
}

void MutaEvent::setPos(const QPointF &pos)
{
    QGraphicsRectItem::setPos(Muta::quantizePointD(pos,30,15));
    emit posChanged(objectID,pos);
}

the next bit is a static function in a namespace called Muta:

static QPointF quantizePoint(QPointF point,double xQuant, double yQuant)
{
    double x = quantize(point.x(),xQuant);
    double y = quantize(point.y(),yQuant);
    QPointF quantPoint(x,y);
    return quantPoint;
}

Any help would be much appreciated!


Solution

  • Take a look at overriding the QGraphicsItem::itemChange protected function. From there you can be notified when an item position is about to change (QGraphicsItem::ItemPositionChange) and have the opportunity to modify the value. This method is called no matter how the change was initiated (mouse move, part of group, set in code, etc.)

    I suspect part of your problem is that QGraphicsItem::setPos() is not virtual, which means that your setPos() function will not be called if a caller is treating an instance of your MutaEvent* as a QGraphicsItem*. This would be the case everywhere in the Qt framework since, of course, they have no knowledge of your MutaEvent class. This is why they provide the virtual itemChange method.