我正在使用QGraphicsScene绘制数百万个多边形。我计划稍后使用Qt + OpenGL,但是现在我没有绘制超过100万个多边形,Qt处理它就好了。当我尝试在多边形内显示文本时出现问题。
每个多边形(继承QGraphicsPolygonItem的自定义类)是对象的可视化表示,并且具有指向与之关联的对象的指针。每个对象都有一个std::string
标识符。如果我只是在多边形内部显示那个字符串,它应该是精细的内存。但是,Qt似乎需要QString
,而且转换每个字符串需要花费大量的时间和空间。我正在为每个多边形创建一个QGraphicsTextObject,每个多边形都需要QString
的{{1}}副本。有没有办法绕过这个副本只使用Qt?
不希望裁剪场景。有些多边形太小,任何文本都不适合它们,人们只能通过放大场景来看到它们。不需要显示这些多边形(及其文本)(除非用户放大),但我认为如果不首先创建各种其他问题,这将有所帮助。
P.S。:可以按需显示文本(例如,当用户将鼠标悬停在每个多边形上时),但是如果文本很容易显示则是理想的。
答案 0 :(得分:1)
您是否对其进行了分析,看看转换是否真的是您的瓶颈?字体渲染并不是很快,如果实际上尝试渲染数百万个文本,那将会很慢。你不会绕过字符串转换,我唯一能想到的就是优化何时做,以及多久。
首先,我考虑使用一个自定义项目,通过重新实现QGraphicsItem :: paint手动绘制文本,或者从中导出。 QGraphicsSimpleTextItem,它允许比直接使用QGraphicsSimpleTextItem甚至QGraphicsTextItem更多调整,这两者都需要你调用setText()并因此预先转换字符串。
要注意的一件事是转换何时完成。 使用自定义项,您不需要预先执行std :: string到QString转换(当调用setText()时),但是您可以存储std :: string并仅在需要时在paint()中执行实现,即在第一次paint()调用时转换然后缓存。
另一个可能很昂贵的计算是boundingRect()。这可以通过返回实际文本形状的不太精确的近似来调整。如果返回的矩形比实际绘制的矩形稍大,它不会受到伤害,它不应该更小。因此可以使用硬编码高度*约。字母宽度+一些填充。
然后,根本没有绘制的文字甚至更便宜。如果视图被缩小,则绘制10 ^ 6个项目(并且仅调用paint()),一个人将很难阅读任何文本。我将重新实现paint()并使用QGraphicsView的详细级别机制(请参阅here)并且不转换字符串,也不会在特定级别的细节/缩放级别下绘制任何内容。
如果您可以使用Qt 5.4,QGraphicsScene::minimumRenderSize也可能会派上用场。但是,如果不与上述其他建议结合使用,那么就不会避免字符串转换和boundingRect()。