У меня есть собственная реализация QGraphicsItem. Я должен быть в состоянии ограничить, где предмет может быть перемещен - я, е. ограничить его до определенной области. Когда я проверял документацию Qt, это было то, что он предлагал:
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);
}
Таким образом, в основном, проверьте позицию, переданную itemChange, и, если она вам не нравится, измените ее и верните новое значение.
Кажется достаточно простым, но на самом деле это не работает. Когда я проверил стек вызовов, я вижу, что itemChange вызывается из QGraphicsItem :: setPos, но он даже не смотрит на возвращаемое значение. Поэтому нет смысла возвращать мне измененную позицию, никто не смотрит на это. Смотрите код из 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();
Есть предложения? Я надеялся избежать повторной реализации всего поведения «щелчок и перетаскивание» самостоятельно с помощью перемещения мыши с помощью мыши и т. Д., Но, полагаю, мне придется это сделать, если я не смогу найти лучшую идею.