2010-12-02 76 views
6

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

有什麼建議嗎?我希望避免重新實現整個點擊和拖動行爲我自己使用鼠標移動鼠標等等,但我想我會不得不如果我找不到更好的主意。

回答

4

我沒有真正嘗試它,但它看起來正在檢查返回位置。返回的限制位置用於newPosVariant的構造函數中以轉換爲newPos。然後用它來設置物品的位置,如果它與當前物品不同。

+1

啊!我看到我的問題。在我的實際代碼中,我正在檢查ItemPositionHasChanged而不是ItemPositionChange。這意味着我所有的位置檢查都是在對itemChange的錯誤調用中發生的 - 它不檢查返回類型。感謝讓我再次看看我在做什麼。這真是愚蠢的我。 – Liz 2010-12-02 16:58:13