My Qt 4.8.1 C++ class to draw a crosshair subclasses QGraphicsItem and implements its paint() and boundingRect() methods. The paint() method consists of two drawLine() and one drawText() calls. The origin is centered. boundingRect() also respects these coordinates (-,-,+,+) and also the half-pen-width in each direction.
When creating, moving (or positioning) and then adding the object to the (visible) scene, the view shifts a few pixels so that the scene contents move slightly to the bottom right. If the boundingRect() returns an empty QRectF(), this shift does not happen.
- additional elements do not cause further movement of the scene.
- a prior update() of the scene does not change the behaviour
- a larger boundingRect seems to increase movement
- changing the view's transform does not change the behaviour
itemChange() is called numerous times but does not seem to provide a clue (in my eyes):
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)
...
I might be able to create a minimal example tomorrow, but maybe someone is able to guess my mistake even from this general description of the problem. Alternatively, hints towards further debugging are of course very welcome!
Edit Thanks Riateche for the advice. Some further debug outputs reveal that the sceneRect() indeed is changed, it expands exactly the size of the Crosshair's bounding rect, e.g. from
QRectF(0,0 1680x636)
to QRectF(-11.5,-11.5 1691.5x647.5)
. The scene's itemsBoundingRect stays the same.
Now I failed to mention previously that the view has been scaled/transformed with fitInView(scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
and noticed that the shift indeed does not occur when the scene is viewed at 100% (e.g. resetTransform()
).
But I still do not understand how/why the sceneRect() changes when I am adding an element within the boundingRect(). It must have to do with my custom implementation, because adding an ellipse does not cause a shift of the scene/view.
Ok, here we go: I also failed to mention that I use setFlag(QGraphicsItem::ItemIgnoresTransformations);
so that the crosshair stays the same size regardless of scale. This apparently causes the boundingrect to "stay" at the scene's origin when added, and ignores the setPos().
To be continued ...