2010-12-02 21 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

Ah!私は私の問題を見る。実際のコードでは、ItemPositionChangeの代わりにItemPositionHasChangedをチェックしていました。つまり、戻り値の型をチェックしていないitemChangeの間違った呼び出しで、すべての位置チェックが行われていました。私がやっていたことをもう一度見てくれてありがとう。それは私の愚かだった。 – Liz

関連する問題