我的QGraphicsScene
中有大约1000个图形项目。我想将所有这1000个项目移动到新位置。新的职位不相互关联,所有职位都应该在同一时间完成。
一种方法是遍历这1000个项目,并为每个项目调用setPos
!我认为这会阻止用户界面。另一种方法是在另一个线程中绘制图像,并将该图像设置为QGraphicsScene的结果!
愿您有另一个想法,我期待着听到!如何在不阻挡UI的情况下在QGraphicsScene中移动1000个项目
回答
如果你了解它是如何工作的,即使你想绘制,例如,1000条鱼都独立移动,Qt绘图可以非常快。
在大量项目的情况下,处理这种情况最糟糕的方式是为每个项目创建一个单独的QGraphicsItem/QGraphicsObject,并尝试独立移动和绘制它们。人们在这里没有意识到的一个主要问题是,当绘画(QPainter *画家...)功能被调用时,他们将笔和笔刷放在画家身上。通常情况下,没关系,但是在内部有这样做的开销,图形管道将会停滞。对于1000件商品,这确实会减慢速度。相反,如果我们将鱼设计为鱼群并创建一个QGraphicsItem,我们可以在内部跟踪它们的位置,并且只需调用一次paint函数。
class SchoolOfFish : QGraphicsObject // QGraphicsObject for signals/slots
{
Q_OBJECT
public:
void UpdateFish();
protected:
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); // overloaded paint function
private:
QList<QPoint> m_fishPositionList;
};
请注意鱼的所有位置都保存在QPoint对象的QList中。有几个优化可以在这里完成。首先,我经常看到人们在绘画功能中更新项目位置,导致表现不佳;只有绘画功能应该在绘画中完成。
更新鱼的位置最初可以在一个计时器上完成,也许瞄准每秒30帧。如果这太慢,那么我们可以创建一个单独的线程来更新所有鱼的位置并将该列表发回到SchoolOfFish对象;所有图形渲染必须在主线程上完成。
这种方法实际上只是把鱼群当做particle system。以这种方式设计系统后,如果需要的话,我希望做的最后一个优化将转向OpenGl。但是请注意,其实你可以得到标准的Qt油漆调用来使用OpenGL作为QWidget的状态的文档
要渲染使用OpenGL,只需调用setViewport(新QGLWidget来绘图)。 QGraphicsView取得了视口控件的所有权。
QGraphicsScene scene; scene.setItemIndexMethod(QGraphicsScene.NoIndex);
这是不是默认
QGraphicsScene.BspTreeIndex
对动态场景快得多,但也是有代价的,因为这需要事件:
谢谢!完美答案。正是我在看的东西! – saeed
Qt QML支持粒子系统:http://qt-project.org/doc/qt-5.0/qtquick/qtquick-particles2-qtquick-effects-particles.html –
对于在Qt中绘制大量项目,通过移动到较低级别的绘制界面可能会更好。例如,OpenGL可以在QWindow上实现(可以将它锚定到主窗口中),请参阅http://qt-project.org/doc/qt-5.0/qtgui/openglwindow.html。 OpenGL可能有点痛苦,但您不必担心阻塞,我目前的项目完全是这样做的,以便在大约100毫秒内呈现300,000个彩色方块。
谢谢。你在哪里学习OpenGL :) – saeed
我链接的例子将让你了解Qt中OpenGL的基础知识。除此之外,你可以阅读普通的OpenGL教程(忽略GLUT这个只是另一个窗口系统的讨论) - 比如http://www.opengl-tutorial.org/或http://lazyfoo.net/tutorials/OpenGL/。 –
动态场景的setPos()
大幅加快可实现查询QGraphicsScene
现在将显着较慢(例如悬停事件)。
另一种加快速度的方法是减少对象的总数。如果场景使用很多QGraphicsItemGroup
,则可以尝试用普通的QGraphicsItem
替换它们,并覆盖它的paint()
方法而不是使用子对象。即使有了这种优化,我发现一旦超过了几百个对象,QGraphicsScene的性能仍然相当悲惨。 QtQuick似乎更好地处理大型对象集合。
- 1. 如何在不阻挡UI的情况下创建UIView
- 2. 如何在不阻挡UI的情况下向WPF程序添加延迟
- 3. 在不阻挡正常控件的情况下阻塞线程
- 4. WPF:如何在不阻止动画的情况下更新UI
- 5. 如何在不阻止InnoSetup UI的情况下执行7zip?
- 6. 在不损坏装配参考的情况下移动项目
- 7. 在不阻挡用户界面的情况下在循环中添加延迟
- 8. 如何在不移动光标的情况下移动屏幕?
- 9. 如何在不复制QGraphicsScene的情况下显示QImage
- 10. 如何在不显示挡板的情况下使用NSTableCellPopup?
- 11. 在不改变分层位置的情况下在IB中移动项目
- 12. 如何在不阻塞UI的情况下将内容加载到TableView中?
- 13. 如何在不暂停的情况下移动动画GIF?
- 14. 等待DataReceived在不阻止UI的情况下触发
- 15. 在不阻挡主线程的情况下添加/重新加载mapview注释
- 16. 布局问题 - 如何在不移动某些UI元素的情况下启动一项活动?
- 17. VBA - 在不唯一的情况下从阵列中移除两个项目
- 18. Nodejs在不删除源目录的情况下移动文件
- 19. 如何在不更换的情况下复制/移动文件
- 20. 如何在不使用操作的情况下移动精灵?
- 21. 如何在不移动的情况下分割div标签?
- 22. 如何在不提交的情况下移动更改?
- 23. 如何在不使CSS移动的情况下跨越元素?
- 24. 如何在不链接到csproj的情况下引用项目?
- 25. 如何在不使用CLI的情况下部署Angular2项目
- 26. 如何在不打开Visual Studio的情况下绑定项目
- 27. 如何在不运行runtime的情况下部署WaveMaker项目
- 28. 如何在不阻止的情况下顺序启动多个程序?
- 29. 如何在QGraphicsScene中添加项目?
- 30. 如何在不阻止滚动的情况下禁用滚动视图滚动
1000个项目通常意味着您的UI设计出了问题,或者您应该进行优化(如果没有更多细节,很难说出有用的东西)。 –
@MarekR:什么?这与UI设计无关!问题很简单:假设你的QGraphicsScene中有1000条鱼,并且你想同时随机移动它们! – saeed
可以在单个容器中更有效地绘制群体物品。一切都取决于细节。无论如何,如果一切正常完成,标准台式机上的1000个简单物品应该不成问题。 –