我有一个自定义的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();
有什么建议吗?我希望避免使用鼠标按下、移动等操作重新实现整个点击和拖动行为,但如果找不到更好的想法,我想我必须这样做。