我有一个自定义的QGraphicsItem实现.我需要能够限制项目的移动位置 - 即e.将其限制在某个区域.当我检查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);
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,检查传递给itemChange的位置,如果你不喜欢它,更改它并返回新值.
看起来很简单,除了它实际上没有用.当我检查调用堆栈时,我看到从QGraphicsItem :: setPos调用了itemChange,但它甚至没有查看返回值.所以没有任何目的让我返回一个改变的位置,没有人在看它.请参阅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();
Run Code Online (Sandbox Code Playgroud)
有什么建议?我希望避免使用鼠标按下鼠标移动等来重新实现整个点击和拖动行为......但是我想如果我找不到更好的主意我将不得不这样做.
我实际上没有尝试过,但在我看来它正在检查返回位置。返回的受限位置在 to 的构造函数中使用,newPosVariant转换为newPos。然后,如果该项目与当前项目不同,则使用它来设置该项目的位置。