I have a custom QGraphicsItem implementation. I need to be able to limit where the item can be moved - i,e. restrict it to a certain area. When I checked the Qt documentation this is what it suggested:
QVariant Component::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
// value is the new position.
QPointF newPos = value.toPointF();
QRectF rect = scene()->sceneRect();
if (!rect.contains(newPos)) {
// Keep the item inside the scene rect.
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
return newPos;
}
}
return QGraphicsItem::itemChange(change, value);
}
So basically, check the position passed to itemChange, and if you don't like it, change it and return the new value.
Seems simple enough, except it doesn't actually work. When I checked the call stack I see that itemChange is being called from QGraphicsItem::setPos, but it doesn't even look at the return value. So there is no purpose to me returning a changed position, no one is looking at it. See code from QGraphicsItem.cpp
// Notify the item that the position is changing.
const QVariant newPosVariant(itemChange(ItemPositionChange, qVariantFromValue<QPointF>(pos)));
QPointF newPos = newPosVariant.toPointF();
if (newPos == d_ptr->pos)
return;
// Update and repositition.
d_ptr->setPosHelper(newPos);
// Send post-notification.
itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
d_ptr->sendScenePosChange();
Any suggestions? I was hoping to avoid re-implementing the whole click and drag behavior myself using mouse-down mouse-move etc..., but I suppose I will have to if I can't find a better idea.
I didn't actually try it but it looks to me it is checking the return position. The returned restricted position is used in the constructor of newPosVariant
to converted to newPos
. It's then used to set the position of the item if it's different from the current one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With