如何在QGraphicsScene中移动1000个项目而不阻塞UI [英] How to move around 1000 items in a QGraphicsScene without blocking the UI

查看:125
本文介绍了如何在QGraphicsScene中移动1000个项目而不阻塞UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 QGraphicsScene 中有大约1000个图形项.我想将所有这1000个项目移到新位置.新职位彼此无关,所有职位都应同时完成.
一种方法是遍历这1000个项目,并为每个项目分别调用 setPos !我认为这将阻止用户界面.另一种方法是在另一个线程中绘制图像,然后将其设置为QGraphicsScene!
可能您还有其他想法.我很期待听到这个消息!

I have around 1000 graphics item in my QGraphicsScene. I want to move all of these 1000 items to new position. New positions don't relate to each other and all of them should be done at the same time.
One way is to iterate through these 1000 items and call setPos for each one ! I think this will block user interface. Another way is to draw an image in another thread and to set this image as a result in QGraphicsScene!
May you have another idea.I'm looking forward to hearing that !

推荐答案

即使您想绘制例如1000条完全独立移动的鱼,Qt绘制也可以很快完成.

Qt drawing can be very quick if you understand how it works, even if you want to draw, for example, 1000 fish all moving independently.

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

In the case of a large number of items, the worst way to handle this is to create a separate QGraphicsItem / QGraphicsObject for each item and try to move and draw them all independently. One major issue people don't realise here is that when the paint(QPainter * painter...) function is called, they set the pen and brush on the painter. Normally, that's ok, but there is an overhead doing this as internally, the graphics pipeline will be stalled. For 1000 items, that's really going to slow things down.

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

Instead, if we design the fish as a school of fish and create just one QGraphicsItem, we can keep track of their positions internally and have the paint function called just once.

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中.在这里可以进行几个优化.首先,我经常看到人们在绘画功能中更新项目位置,这会导致性能下降;只能在绘画中完成绘图功能.

Note that all the positions of the fish are kept in a QList of QPoint objects. There are several optimisations that can be done here. Firstly, I often see people updating item positions in the paint function, which causes poor performance; Only drawing functionality should be done in paint.

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

Updating the fish positions can initially be done on a timer, perhaps aiming for 30 frames per second. If this is too slow, then we could create a separate thread that updates all the fish positions and emits the list back to the SchoolOfFish object; all graphics rendering must be done on the main thread.

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

This method is actually just treating the school of fish as a particle system. After designing the system this way, if required, the last optimisation I'd look to make would be moving to OpenGl. However, note that you can actually get the standard Qt paint calls to use OpenGl as the docs of QWidget state

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

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

这篇关于如何在QGraphicsScene中移动1000个项目而不阻塞UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆