我的Qt 4.8.1 C ++类用于绘制十字准线子类QGraphicsItem并实现其paint()和boundingRect()方法。 paint()方法由两个drawLine()和一个drawText()调用组成。原点是中心的。 boundingRect()也尊重这些坐标( - , - ,+,+)以及每个方向的半笔宽度。
创建,移动(或定位)然后将对象添加到(可见)场景时,视图会移动几个像素,以便场景内容稍微向右移动。 如果boundingRect()返回一个空的QRectF(),则不会发生这种转变。
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()确实被改变,它完全扩展了Crosshair的边界矩形的大小,例如从
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()。
继续......
答案 0 :(得分:3)
场景有一个边界矩形,默认情况下是包含所有项目的最小矩形。如果向此矩形之外的场景添加内容,则会扩展边界矩形。
视图尊重场景的矩形。如果场景的rect小于视图的视口大小,则视图的滚动条将被隐藏,场景内容将在视口的中心中显示。因此,如果添加一个项目,场景的边界矩形会发生变化,所有内容都会被移动。如果视口小于边界rect,则会出现滚动条。
如果您想避免此行为,可以使用QGraphicsView::setSceneRect
或QGraphicsScene::setSceneRect
来修正矩形位置。请注意,设置矩形之外的所有内容都将在视图中不可用且不可见。
另请考虑切换为QGraphicsPathItem
(和QGraphicsScene::addPath
)。它可以用来绘制十字准线。
答案 1 :(得分:0)
我正在尝试是否可以使用
解决问题QRectF save = scene->sceneRect();
scene->addItem( myGraphicsItem );
scene->setSceneRect( save );
正如Riateche所说的不同,并且它有效。
然而,遗憾的是,我仍然不完全了解其原因。
以下是documentation对此标志的评价:
QGraphicsItem :: ItemIgnoresTransformations
0x20
该项目忽略 继承的变换(即,它的位置仍然固定在其上 父级,但父级或视图旋转,缩放或剪切变换 被忽略了)。此标志对于保留文本标签项非常有用 水平和非标度,因此如果视图是可读的,它们仍然是可读的 转化。设置时,项目的视图几何和场景几何 将单独维护。您必须调用deviceTransform()进行映射 坐标并检测视图中的碰撞。默认情况下,此标志 被禁用。这个标志在Qt 4.3中引入。注意:有了这个标志 设置您仍然可以缩放项目本身,以及该比例转换 会影响该项目的孩子。
以下是一些可能相关的信息: