2016-10-31 44 views
2

有沒有人有更好的方法來約束一個QGraphicsItem的孩子到場景?約束子QGraphicsItem到場景?

我已經通過重寫itemChange成功地將父母QGraphicsItem正確地約束到它的場景,但現在我需要爲子QGraphicsItem做同樣的事情。

示例使用情況:

An Example Use Case with two handles (children) and a bar (parent)

此代碼的工作......在大多數情況下。唯一的問題是QGraphicsItem的速度擊中兩側,當會影響其擋塊位置

QVariant SizeGripItem::HandleItem::itemChange(GraphicsItemChange change, 
               const QVariant &value) 
{ 
    QPointF newPos = value.toPointF(); 
    if (change == ItemPositionChange) 
    { 
     if(scene()) 
     { 
      newPos.setY(pos().y()); // Y-coordinate is constant. 

      if(scenePos().x() < 0) //If child item is off the left side of the scene, 
      { 
       if (newPos.x() < pos().x()) // and is trying to move left, 
       { 
        newPos.setX(pos().x()); // then hold its position 
       } 
      } 
      else if(scenePos().x() > scene()->sceneRect().right()) //If child item is off the right side of the scene, 
      { 
       if (newPos.x() > pos().x()) //and is trying to move right, 
       { 
        newPos.setX(pos().x()); // then hold its position 
       } 
      } 
     } 
    } 
return newPos; 
} 

父項,我用: newPos.setX(qMin(scRect.right(), qMax(newPos.x(), scRect.left()))); 它完美地工作,但我難倒,以如何或如果我可以在這裏使用它。

+0

要現場或查看? – dtech

+0

問題在於在調用'setPos'之前添加速度的代碼,您不需要在'itemChange'中執行此操作。你可以顯示該代碼嗎? – TheDarkKnight

+0

我沒有那個代碼。滑塊只能像鼠標拖動一樣快。 –

回答

2

首先,具體來說,場景實際上沒有邊界。你想要做的是將項目限制到你在別處設置的場景矩形。

我看到的問題是在您使用scenePos。這是一個ItemPositionChange;該物品的scenePos尚未更新爲新的位置,因此當您檢查scenePos離開場景矩形時,您確實檢查了上次位置變化的結果,而不是當前的位置變化。正因爲如此,您的物品剛剛離開場景矩形的邊緣,然後粘在那裏。邊距有多遠取決於你移動鼠標的速度,這決定了ItemPositionChange通知之間的距離。

相反,您需要將新位置與場景矩形進行比較,然後限制返回到場景矩形內的值。您需要在場景中的新位置座標做比較,所以你需要像:

QPoint new_scene_pos = mapToScene (new_pos); 

if (new_scene_pos.x() < scene()->sceneRect().left()) 
    { 
    new_scene_pos.setX (scene()->sceneRect().left()); 
    new_pos = mapFromScene (new_scene_pos); 
    } 

這是不完整的代碼,很明顯,但這些都是你需要做的,以保持它在轉換和檢查在左側。右側非常相似,所以只需使用new_scene_pos進行比較即可。

請注意,我沒有假設sceneRecT的左邊緣位於0.我確定這就是您設置sceneRect的位置,但使用實際的左值而不是假設它爲0可以消除任何問題if你最終會改變你計劃使用的場景座標的範圍。

我在sceneRect調用中使用「left」而不是「x」,僅僅是因爲它使用「right」來平行對另一側。他們完全一樣,但我認爲在這種情況下它略好一些。

+0

'mapToScene'是我需要研究的功能。我修改了'mapFromScene','mapToScene','mapFromParent'和'mapToParent'後,發現了我所需要的:'mapToScene(mapFromParent(newPos))' –

相關問題