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

StackOverflow https://stackoverflow.com/questions/7014679

سؤال

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!

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Are all the selected items your MutaEvent class? setPos() is called on each selected item so if not it would just use the default implementation.

You might need to implement your own mouse event handling if you want it to work properly (and by the way, calling setPos(pos()) in MutaEvent::mouseMoveEvent will have no effect).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top