1

十字線を描画するための私の Qt 4.8.1 C++ クラスは、QGraphicsItem をサブクラス化し、そのpaint()およびboundingRect()メソッドを実装します。paint() メソッドは、2 つの drawLine() 呼び出しと 1 つの drawText() 呼び出しで構成されます。原点が中心です。また、boundingRect() は、これらの座標 (-、-、+、+) と、各方向の半ペン幅も考慮します。

オブジェクトを作成、移動 (または配置) し、(表示されている) シーンに追加すると、シーンのコンテンツが右下にわずかに移動するように、ビューが数ピクセル移動します。boundingRect() が空の QRectF() を返す場合、このシフトは発生しません。

  • 追加の要素によってシーンがさらに移動することはありません。
  • シーンの以前の update() は動作を変更しません
  • より大きなboundingRectは動きを増やすようです
  • ビューの変換を変更しても動作は変わりません

itemChange() は何度も呼び出されますが、手がかりを提供していないようです(私の目には):

Crosshair::Crosshair being created, id= "1"  at  QPointF(63.6, 88.487) scenePos= QPointF(33.6, 58.487) 
Crosshair::Crosshair position QPointF(63.6, 88.487) 
Crosshair::itemChange  ItemFlagsChange QVariant(uint, 1) 
Crosshair::itemChange  ItemFlagsHaveChanged QVariant(uint, 1) 
Crosshair::itemChange  ItemFlagsChange QVariant(uint, 33) 
Crosshair::itemChange  ItemFlagsHaveChanged QVariant(uint, 33) 
Crosshair::itemChange  ItemFlagsChange QVariant(uint, 2081) 
Crosshair::itemChange  ItemFlagsHaveChanged QVariant(uint, 2081) 
[...]
Crosshair::itemChange  ItemPositionChange QVariant(QPointF, QPointF(63.6, 88.487) ) 
Crosshair::itemChange  ItemPositionHasChanged QVariant(QPointF, QPointF(63.6, 88.487) ) 
Crosshair::itemChange  ItemSceneChange QVariant(QGraphicsScene*, ) 
Crosshair::itemChange  ItemSceneHasChanged QVariant(QGraphicsScene*, ) 
[...]
Crosshair::boundingRect  20 3 QRectF(-11.5,-11.5 21.5x21.5) 
Crosshair::boundingRect  20 3 QRectF(-11.5,-11.5 21.5x21.5) 
Crosshair::itemChange  ItemVisibleChange QVariant(bool, true) 
Crosshair::itemChange  ItemVisibleHasChanged QVariant(bool, true) 
Crosshair::boundingRect  20 3 QRectF(-11.5,-11.5 21.5x21.5) 
Crosshair::boundingRect  20 3 QRectF(-11.5,-11.5 21.5x21.5) 
...

明日には最小限の例を作成できるかもしれませんが、この問題の一般的な説明からでも誰かが私の間違いを推測できるかもしれません。あるいは、さらにデバッグするためのヒントはもちろん大歓迎です!


編集 アドバイスをくれた Riateche に感謝します。さらにデバッグ出力を確認すると、sceneRect() が実際に変更されていることがわかります。たとえば、 からQRectF(0,0 1680x636)に、クロスヘアの境界矩形のサイズを正確に拡張しQRectF(-11.5,-11.5 1691.5x647.5)ます。シーンの itemsBoundingRect は同じままです。ここで、ビューが でスケーリング/変換されていることを前に言及し損ねましたがfitInView(scene()->itemsBoundingRect(), Qt::KeepAspectRatio);、シーンを 100% で表示したときに実際にシフトが発生しないことに気付きました (例: resetTransform())。しかし、boundingRect() 内に要素を追加すると、sceneRect() がどのように/なぜ変化するのかまだわかりません。楕円を追加してもシーン/ビューがシフトしないため、カスタム実装に関係している必要があります。

わかりました、ここに行きます: またsetFlag(QGraphicsItem::ItemIgnoresTransformations);、縮尺に関係なく十字線が同じサイズのままになるように使用することにも言及しませんでした。これにより、追加時に境界矩形がシーンの原点に「とどまる」ようになり、setPos() が無視されます。

つづく ...

4

2 に答える 2

0

問題を回避できるかどうかを試していました

QRectF save = scene->sceneRect();
scene->addItem( myGraphicsItem );
scene->setSceneRect( save );

Riatecheが別のメモで示唆しているように、それは機能します.

しかし、残念ながら私はまだこの原因を完全には理解していません。

このフラグに関するドキュメントの説明は次のとおりです。

QGraphicsItem::ItemIgnoresTransformations

0x20

アイテムは継承された変換を無視します (つまり、その位置は依然として親に固定されていますが、親またはビューの回転、ズームまたはせん断変換は無視されます)。このフラグは、テキスト ラベル アイテムを水平に保ち、拡大縮小しない場合に役立ちます。これにより、ビューが変換されても読み取り可能になります。設定すると、アイテムのビュー ジオメトリとシーン ジオメトリが別々に維持されます。座標をマップし、ビュー内の衝突を検出するには、deviceTransform() を呼び出す必要があります。デフォルトでは、このフラグは無効になっています。このフラグは Qt 4.3 で導入されました。注: このフラグを設定してもアイテム自体をスケーリングでき、そのスケーリング変換はアイテムの子に影響を与えます。

関連する可能性のある情報を次に示します。

于 2013-07-12T09:13:53.917 に答える