2013-07-09 67 views
1

我的Qt 4.8.1 C++類繪製十字線的子類QGraphicsItem並實現其paint()boundingRect()方法。 paint()方法由兩個drawLine()和一個drawText()調用組成。原點居中。 boundingRect()也遵循這些座標( - , - ,+,+)以及每個方向上的半筆寬度。爲什麼自定義的QGraphicsItem會導致場景或視圖移動,除非boundingRect爲空?

創建,移動(或定位)然後將對象添加到(可見)場景時,視圖會移動幾個像素,以便場景內容略微向右下移動。 如果boundingRect()返回一個空的QRectF(),則不會發生這種移位。

  • 附加元素不會導致場景的進一步移動。
  • 事先更新的場景()不改變行爲
  • 較大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);,這樣十字準線就可以保持相同的大小,而不管規模。這顯然會導致boundingrect在添加時「停留」在場景的原點,並忽略setPos()。

待續...

回答

3

場景有一個邊框默認情況下是包含所有項目的最小的矩形。如果您將某些東西添加到此矩形之外的場景中,則邊界矩形將被展開。

視圖尊重場景的矩形。如果場景的矩形小於視圖的視口大小,則視圖的滾動條將隱藏,場景內容將在視口的中心處出現。所以,如果你添加一個項目,場景的邊界矩形會改變,所有內容都會被移動。如果視口小於邊界矩形,則出現滾動條。

如果要避免此行爲,可以使用QGraphicsView::setSceneRectQGraphicsScene::setSceneRect來修復矩形位置。請注意,設置矩形外的所有內容在視圖中將不可用且不可見。

另請考慮切換到QGraphicsPathItem(和QGraphicsScene::addPath)。它可以用來繪製十字線。

0

我是想是否該問題可能與

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

爲Riateche表明在不同的音符來合作周圍,和它的作品。

但是,不幸的是我還是不完全明白這個原因。

下面介紹一下documentation不得不說的這個標誌:

的QGraphicsItem :: ItemIgnoresTransformations

爲0x20

項忽略 繼承變換(即,它的位置仍然是錨定在其 親本,但忽略父視圖或視圖旋轉,縮放或剪切轉換 )。此標誌對於保持文本標籤項目 水平和未縮放非常有用,因此如果視圖變換爲 ,它們仍然可讀。設置時,項目的視圖幾何圖形和場景幾何圖形 將單獨維護。您必須調用deviceTransform()來映射 座標並檢測視圖中的碰撞。默認情況下,此標誌 已禁用。這個標誌是在Qt 4.3中引入的。注意:使用此標誌 設置,您仍然可以縮放項目本身,並且該比例轉換 將影響項目的子項目。

下面是一些可能的相關信息:

相關問題