QGraphicsItem验证位置更改

6

我有一个自定义的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();

有什么建议吗?我希望避免使用鼠标按下、移动等操作重新实现整个点击和拖动行为,但如果找不到更好的想法,我想我必须这样做。

1个回答

4

我没有实际尝试过,但在我的看法中,它正在检查返回位置。返回的受限位置用于newPosVariant的构造函数中转换为newPos。然后,如果该位置与当前位置不同,则用于设置项目的位置。


1
啊!我发现了问题。在我的实际代码中,我检查的是ItemPositionHasChanged而不是ItemPositionChange。这意味着所有的位置检查都发生在错误的itemChange调用中——那个不检查返回类型的调用。谢谢你让我再次审视自己的工作。我真是太傻了。 - Liz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接