QGraphicsItem验证位置变化

问题描述:

我有一个自定义的QGraphicsItem实现。我需要能够限制物品可以移动的位置 - 例如,将其限制在某个区域。当我检查了Qt文档这是它建议:QGraphicsItem验证位置变化

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(); 

有什么建议吗?我希望避免重新实现整个点击和拖动行为我自己使用鼠标移动鼠标等等,但我想我会不得不如果我找不到更好的主意。

我没有真正尝试它,但它看起来正在检查返回位置。返回的限制位置用于newPosVariant的构造函数中以转换为newPos。然后用它来设置物品的位置,如果它与当前物品不同。

+1

啊!我看到我的问题。在我的实际代码中,我正在检查ItemPositionHasChanged而不是ItemPositionChange。这意味着我所有的位置检查都是在对itemChange的错误调用中发生的 - 它不检查返回类型。感谢让我再次看看我在做什么。这真是愚蠢的我。 – Liz 2010-12-02 16:58:13