【问题标题】:Qt: Custom QGraphicsItem not showing when boundingRect() center is out of viewQt:当boundingRect()中心不在视野范围内时,自定义QGraphicsItem不显示
【发布时间】:2014-10-21 00:32:29
【问题描述】:

我正在制作一个图表(Fluxogram)程序,几天来我一直被这个问题困扰:

我有一个自定义的QGraphicsScene,只要我将一个项目放在它最右边的区域,它就会水平扩展。问题是我的自定义箭头(它们继承QGraphicsPathItem)在boundingRect() 中心滚动离开视图时从场景中消失。每次场景扩展时,sceneRect() 和视图的 sceneRect() 都会更新。

我已经:

set ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate)

项目标志QGraphicsItem::ItemIgnoresTransformations和QGraphicsItem::ItemSendsGeometryChanges,setActive(true)也在项目上,每次我向场景添加箭头时,我都会调用update(sceneRect())方法。尽管如此,每次我滚动视图时,只要箭头的boundingRect() 中心远离视图,所有箭头都会消失。如果我向后滚动并且 boundingRect() 中心进入视图,所有的箭头都会再次出现。

有人可以告诉我我可能缺少什么吗?我一直在使用 Qt 的示例项目图表场景作为参考,所以我的很多代码都是相似的(“按项目工具按钮 -> 单击场景”关系插入项目,它们放置箭头以连接对象的方式,。 ..)。

与此同时,我将尝试制作一个可以显示我的问题的最小运行示例。

【问题讨论】:

  • 我做了一个最简单的例子,我可以保留我迄今为止用来解决这个问题的方法。我已经粘贴到pastebin了(不知道这里能不能用,所以如果不是应该怎么做请告诉我,只是为了确定定位和重新调整场景有很多编码): 头文件:pastebin.com/43Vzkrkq; C++ 文件:pastebin.com/aLuE5Yg4;用户界面文件:pastebin.com/1mHWL0hG
  • 我怀疑问题出在项目的 boundingRect 上。尝试在paint函数中绘制它,看看它是否是您期望看到的。
  • 就是,它绘制了箭头连接的 2 个项目周围的矩形。问题是当我们在网格的最右边添加一些项目时,场景会水平扩展,如果我们滚动,只要 boundingRect 中心(项目的 (0,0) )离开视图的视线,整个箭头消失了,如果我们滚动直到中心再次可见,整个箭头就会再次出现。我需要的是让箭头始终可见,无论可见区域有多小。

标签: c++ qt qgraphicsitem qgraphicsscene


【解决方案1】:

您的 Arrow 对象继承自 QGraphicsPathItem,我希望它也实现 QGraphicsItem::shape 函数。

重写 Arrow 类中的 shape 函数,以返回项目的形状。这与 boundingRect 一起用于碰撞检测和屏幕上项目的检测。

另外,在通过改变boundingRect来改变item的形状之前,需要调用prepareGeometryChange。

如文档所述:-

准备项目以进行几何更改。在更改项目的边界矩形之前调用此函数以使 QGraphicsScene 的索引保持最新。

因此,在 Arrow 类中,存储一个名为 m_boundingRect 的 QRectF 并在构造函数中:-

prepareGeometryChange();
m_boundingRect = QRectF(-x, -y, x*2, y*2);

然后在boundingRect()函数中返回m_boundingRect。

如果这仍然是一个问题,我认为是 QGraphicsPainterPath 中的某些东西导致了问题,在这种情况下,您可以简单地从 QGraphicsItem 继承并存储一个 QPainterPath,您可以使用该 QPainterPath 在项目的绘制函数中绘制并返回画家路径在形状()中。

【讨论】:

  • 刚做了,箭头还是消失了(我是通过将paint()方法的路径定义替换为构造函数,并将其保存在箭头上预定义的变量中来实现的。 h;paint 方法只是调用painter->drawPath(«path_variable_name»);)。
  • 听起来不错 - 不必在绘制函数中计算对象会更快。我已经更新了答案,因为您错过了对 prepareGeometryChange 的调用。
  • 它们仍然消失 :( 接下来我什至在调用 prepareGeometryChange() 之后立即调用 update,认为它可能需要在对构造函数的 m_boundingRect 进行更改后强制更新 boundingRect,但没有成功。
  • 通过在油漆中绘制边界矩形及其坐标来显示它。当你滚动视图时,坐标会改变吗?
  • 我错过了 7 个代表,但只要我有他们,我就会投票,我非常感谢你今天花时间帮助我,非常感谢:D
【解决方案2】:

你把你的生活弄得太复杂了。不要子类化QGraphicsPathItem,只需使用它并在每次锚点位置(从到)发生变化时更新其path 值。

【讨论】:

  • 问题是anchors的位置永远不会改变,唯一改变的是graphicsView的可视区域,当场景的水平长度大于视图的。
  • 更好(更简单)。只需生成所需的路径集,将其设置为QGraphicsPathItem,它就会像魅力一样工作。你没有手动绘制,也没有计算boundingRect。
  • 我试过了,确实箭头没有消失(虽然定位搞砸了,但那是代码调整的问题),但后来我记得在程序的开发中进一步如果我删除一个带有箭头的项目,我需要擦除箭头,如果我只是绘制路径,那么如果它们不是项目,我将无法删除它们,我错了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多