gpt4 book ai didi

c++ - 为什么自定义 QGraphicsItem 会导致场景或 View 移动,除非 boundingRect 为空?

转载 作者:行者123 更新时间:2023-11-30 02:53:55 33 4
gpt4 key购买 nike

我的 Qt 4.8.1 C++ 类绘制十字准线子类 QGraphicsItem 并实现其 paint()boundingRect()方法。paint() 方法由两次 drawLine() 和一次 drawText() 调用组成。原点居中。boundingRect() 还考虑这些坐标(-、-、+、+)以及每个方向的半笔宽。

当创建、移动(或定位)然后将对象添加到(可见)场景时, View 会移动几个像素,以便场景内容稍微移动到右下角。如果 boundingRect() 返回一个空的 QRectF(),则不会发生这种转变。

  • 其他元素不会导致场景进一步移动。
  • 场景的先前更新()不会改变行为
  • 较大的 boundingRect 似乎会增加运动
  • 改变 View 的变换不会改变行为

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 保持不变。现在我之前没有提到 View 已使用 fitInView(scene()->itemsBoundingRect(), Qt::KeepAspectRatio); 进行了缩放/转换,并注意到当以 100% 比例查看场景(例如 resetTransform())。但是我仍然不明白当我在 boundingRect() 中添加元素时 sceneRect() 如何/为什么会发生变化。这一定与我的自定义实现有关,因为添加椭圆不会导致场景/ View 发生偏移。

好吧,我们开始吧:我也没有提到我使用了 setFlag(QGraphicsItem::ItemIgnoresTransformations); 以便无论比例如何,十字准线都保持相同的大小。这显然会导致 boundingrect 在添加时“停留”在场景的原点,并忽略 setPos()。

待续...

最佳答案

场景有一个边界矩形,默认情况下它是包含所有项目的最小矩形。如果您在此矩形之外的场景中添加某些内容,则边界矩形将被扩展。

View 尊重场景的矩形。如果场景的矩形小于 View 的视口(viewport)大小, View 的滚动条将被隐藏,场景内容显示在视口(viewport)的中心。因此,如果您添加一个项目,场景的边界矩形会发生变化并且所有内容都会发生变化。如果视口(viewport)小于边界矩形,则会出现滚动条。

如果您想避免这种行为,您可以使用QGraphicsView::setSceneRectQGraphicsScene::setSceneRect 来固定矩形位置。请注意,设置矩形之外的所有内容在 View 中都不可用且不可见。

同时考虑切换到 QGraphicsPathItem(和 QGraphicsScene::addPath)。它可以用来画十字准线。

关于c++ - 为什么自定义 QGraphicsItem 会导致场景或 View 移动,除非 boundingRect 为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17553530/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com