如何在QGraphicsScene中移动1000个项目而不阻止UI

s4e*_*eed 4 c++ qt qgraphicsscene

我的大约有1000个图形项目QGraphicsScene.我想把所有这1000件物品都搬到新的位置.新职位彼此无关,所有职位都应同时完成.
一种方法是遍历这1000个项目并呼叫setPos每个项目!我认为这将阻止用户界面.另一种方法是在另一个线程中绘制图像,并在QGraphicsScene中设置此图像!
愿你有另一个想法.我很期待听到这个消息!

The*_*ght 8

Qt绘图可以非常快速,如果您了解它的工作原理,即使您想绘制,例如,1000条鱼都独立移动.

在大量项目的情况下,处理此问题的最糟糕方式是为每个项目创建单独的QGraphicsItem/QGraphicsObject,并尝试独立移动和绘制它们.人们在这里没有意识到的一个主要问题是,当调用油漆(QPainter*painter ...)功能时,他们会在画家上设置笔和画笔.通常,这没关系,但是在内部进行这样的开销,图形管道将停滞不前.对于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;
};
Run Code Online (Sandbox Code Playgroud)

请注意,鱼的所有位置都保存在QPoint对象的QList中.有几种优化可以在这里完成.首先,我经常看到人们在绘画功能中更新项目位置,导致性能不佳; 只应在绘画中完成绘图功能.

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

这种方法实际上只是将鱼群视为粒子系统.以这种方式设计系统后,如果需要,我想要进行的最后一次优化将转移到OpenGl.但是,请注意,您实际上可以获得标准的Qt绘制调用,以使用OpenGl作为QWidget状态的文档

要使用OpenGL渲染,只需调用setViewport(new QGLWidget).QGraphicsView获取视口窗口小部件的所有权.