2016-10-24 8 views
2

X軸のスクロールバーとして機能するようにネイティブの動作を変更せずにQGraphicsItem(具体的にはQGraphicsRectItem)の動きを適切に抑制しようとしています。mouseMoveEventでQGraphicsItemの動きを制限する

mouseMoveEvent関数をオーバーライドしようとしましたが、X方向とY方向の両方で長方形の動作を書き直す必要があります。私はマウスを使って単一の位置にスナップすることができます。 (ここでは長方形はそうスナップされますマウスは途中でそれを保持している):

void SegmentItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 
{ 
    setY(0); 
    setX(event->scenePos().x() - boundingRect().width()/2); 
} 

hereが説明するように、私は、今itemChangeで探していますが、それは少し扱いに​​くく、正確にエレガントではないに見えます。 編集:これは動作するはずですが、現在は動作させるために強制できません。

y軸の動きを制限する方法はありますか? (私はまた後でスクロールバーのエンドストップを作成する必要がありますが、されます)

+1

itemChangeソリューションはリンクされています解決法ですが、実際には非常にエレガントです – Fabio

+0

クールですが、現在は何も制約していないようです。私は_「デフォルトの実装は何もせず、値を返します」_ [クラスリファレンスページ](http://doc.qt.io/qt-4.8/qgraphicsitem.html#itemChange)必要なものを知っていますか変更するには? –

答えて

1

私はitemChangeクラスリファレンスページからコードで手を加え、そして私のQGraphicsRectItemのすべての四隅がQGraphicsScene以内にとどまるので、それを強化:

QVariant SegmentItem::itemChange(GraphicsItemChange change, const QVariant &value) 
{ 
    if (change == ItemPositionChange && scene()) { 
     // value is the new position. 
     QPointF newPos = value.toPointF(); 
     QRectF rect = scene()->sceneRect(); 
     rect.setWidth(rect.width() - boundingRect().width()); 
     rect.setHeight(0); 
     if (!rect.contains(newPos)) { 
      // Keep the item inside the scene rect. 
      newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left()))); 
      newPos.setY(2); 
      return newPos; 
     } 
    } 
    return QGraphicsItem::itemChange(change, value); 
} 
1

あなたの質問の他の部分は、一方向だけに動きを制限することについて答えるには...上記の答えに記載されているのと同じitemChange構造を使用してください。追加する必要があるのは、アイテムの現在のX座標またはY座標を戻す前に新しい位置に転送することだけです。この行は、Yは、マウスを追跡することができますが、Xと同じに保つ(すなわち移動が垂直に制限されている):

同様
newPos.setX (this->pos().x()); 

、Xは、マウスを追跡することができますが、同じYを維持するために(つまり、移動が制限されています)水平に:

ItemPositionChange通知で
newPos.setY (this->pos().y()); 

、アイテムの現在位置がまだ変更されていないので、あなたは、新しい値を返す前に新しい位置にあなたが好きなように操作することができます。

+0

クールなので、物事も楽になります! –