J'ai une implémentation QGraphicsItem personnalisée. Je dois être en mesure de limiter où l'élément peut être déplacé - je, e. restreindre à une certaine zone. Lorsque j'ai vérifié la documentation Qt est ce ce qu'il suggère:QGraphicsItem validant un changement de position
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);
}
Donc, fondamentalement, vérifier la position passée à itemChange, et si vous ne l'aimez pas, changer et retourner la nouvelle valeur.
Semble assez simple, sauf qu'il ne fonctionne pas réellement. Quand j'ai vérifié la pile d'appels, je vois que itemChange est appelé depuis QGraphicsItem :: setPos, mais il ne regarde même pas la valeur de retour. Il n'y a donc aucune raison pour que je retourne une position modifiée, personne ne la regarde. Voir le code 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();
Des suggestions? J'espérais éviter de ré-implémenter tout le comportement de cliquer-glisser moi-même en utilisant le mouse-down mouse-move etc ..., mais je suppose que je devrai si je ne peux pas trouver une meilleure idée.
Ah! Je vois mon problème. Dans mon code actuel, je vérifiais ItemPositionHasChanged au lieu de ItemPositionChange. Ce qui signifie que toutes mes vérifications de position se passaient dans le mauvais appel à itemChange - celui qui ne vérifie pas le type de retour. Merci de m'avoir fait regarder à nouveau ce que je faisais. C'était idiot de ma part. – Liz