c++ - 如何在不阻塞 UI 的情况下在 QGraphicsScene 中移动大约 1000 个项目

标签 c++ qt qgraphicsscene

我的 QGraphicsScene 中有大约 1000 个图形项目。我想将所有这 1000 个项目移动到新位置。新职位互不相关,所有职位应同时完成。
一种方法是遍历这 1000 个项目并为每个项目调用 setPos!我认为这会阻止用户界面。另一种方法是在另一个线程中绘制图像并将此图像设置为 QGraphicsScene 中的结果!
也许你有另一个想法。我很期待听到这个消息!

最佳答案

如果您了解 Qt 的工作原理,即使您想绘制 1000 条独立移动的鱼,Qt 绘图也会非常快。

在有大量项目的情况下,最糟糕的处理方式是为每个项目创建一个单独的 QGraphicsItem/QGraphicsObject 并尝试独立移动和绘制它们。人们在这里没有意识到的一个主要问题是,当调用 paint(QPainter * painter...) 函数时,他们将笔和画笔设置在 painter 上。通常情况下,这没问题,但在内部执行此操作会产生开销,图形管道将停滞。对于 1000 个项目,这确实会减慢速度。

相反,如果我们将鱼设计为一群鱼并只创建一个 QGraphicsItem,我们可以在内部跟踪它们的位置并只调用一次绘制函数。

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 中。这里可以进行多项优化。首先,我经常看到有人在 paint 函数中更新项目位置,这会导致性能不佳;只有绘图功能应该在 paint 中完成。

更新鱼的位置最初可以在计时器上完成,目标可能是每秒 30 帧。如果这太慢,那么我们可以创建一个单独的线程来更新所有鱼的位置并将列表发回给 SchoolOfFish 对象;所有图形渲染都必须在主线程上完成。

这个方法其实就是把鱼群当作一个particle system .以这种方式设计系统后,如果需要,我希望进行的最后优化将转移到 OpenGl。但是,请注意,您实际上可以获得标准的 Qt 绘制调用以使用 OpenGl 作为 QWidget 状态的文档

To render using OpenGL, simply call setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport widget.

关于c++ - 如何在不阻塞 UI 的情况下在 QGraphicsScene 中移动大约 1000 个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18397603/

相关文章:

c++ - 无符号字符数组的十进制 ascii 值

qt - 从 QGraphicsScene 中删除单个项目/QLineF

c++ - 使用简单的构造函数

C++ 在堆栈中分配类,而不是在堆中

c++ - char[N] 与 char *

python - PyQT按钮点击不起作用

c++ - 无法打开源文件 "windows.h" "WTypes.h"

qt - 每当用户滚动 QScrollArea 时获得通知的最简单方法是什么?

c++ - 使用 QGraphicsView 方法 Scene() 分配 QGraphicsScene 变量

python - 使 QGraphicsItem 只能在一个图形 View 中选择