2016-10-31 7 views
2

誰かがQGraphicsItemの子供をあるシーンに拘束する良い方法はありますか?子QGraphicsItemをシーンに制限しますか?

itemChangeをオーバーライドすることによって、親シーンQGraphicsItemを正常に正しく拘束しましたが、今度は子供のために同じようにする必要がありますQGraphicsItem

使用例・ケース:

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

このコードは動作します...ほとんどの部分。私が使用し、親項目について

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()))); をどちらかの側を打つとき唯一の問題は、そのエンドストップ位置に影響を与えますQGraphicsItemの速度であり、それをどうやって使うことができますか?

+0

シーンを見たり表示するには? – dtech

+0

問題は、 'setPos'を呼び出す前に速度を追加するコードにあります。これは' itemChange'でこれを行う必要はありません。そのコードを表示できますか? – TheDarkKnight

+0

私はそのコードを持っていません。スライダはマウスがドラッグするのと同じ速さで動きます。 –

答えて

2

まず、具体的には、シーンには効果的に境界がありません。あなたがしようとしているのは、あなたが別の場所に設定したシーン矩形にアイテムを制限することです。

私が見る問題は、あなたのscenePosを使用することです。これはItemPositionChangeです。アイテムのscenePosがまだ新しい位置で更新されていないので、scenePosがシーンrectから外れているかどうかをチェックすると、現在の位置の変更ではなく、最後の位置の変更の結果が実際に確認されます。そのため、アイテムはシーン矩形の端からちょうど外に出てしまい、そこにくっついてしまいます。マウスの動きの速さによって、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であると仮定するのではなく、後で、作業を計画しているシーン座標の範囲を変更することになります。

sceneRectの呼び出しで、 "x"の代わりに "left"を使用しました。これは、もう一方の側に "right"を使用することと平行しているからです。それらはまったく同じですが、このケースでは少し上手く読めると思います。

+0

'mapToScene'は私が研究に必要な機能でした。 'mapFromScene'、' mapToScene'、 'mapFromParent'、' mapToParent'で微調整した後、私は必要なものを見つけました: 'mapToScene(mapFromParent(newPos))' –

関連する問題