Tengo una implementación personalizada de QGraphicsItem. Necesito poder limitar dónde se puede mover el artículo: i, e. restringirlo a un área determinada. Cuando comprobé la documentación de Qt esto es lo que sugiere:QGraphicsItem validación de un cambio de posición
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);
}
Así que, básicamente, comprobar la posición pasó a itemChange, y si no te gusta, cambiarlo y volver el nuevo valor.
Parece bastante simple, excepto que en realidad no funciona. Cuando revisé la pila de llamadas, veo que ItemChange se llama desde QGraphicsItem :: setPos, pero ni siquiera mira el valor devuelto. Entonces no hay ningún propósito para mí que devuelva una posición modificada, nadie lo está mirando. Ver código de 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();
¿Alguna sugerencia? Esperaba evitar volver a implementar todo el comportamiento de hacer clic y arrastrar usando el movimiento del mouse hacia abajo, etc., pero supongo que tendré que hacerlo si no puedo encontrar una mejor idea.
¡Ah! Veo mi problema En mi código actual, estaba verificando ItemPositionHasChanged en lugar de ItemPositionChange. Lo que significa que todas las comprobaciones de mi posición estaban sucediendo en la llamada incorrecta a ItemChange - la que no marca el tipo de devolución. Gracias por hacerme ver de nuevo lo que estaba haciendo. Eso fue tonto de mi parte – Liz