关于Qt多线程仍然卡顿的问题

在一个QGraphicsItem类里的paint,绘制当前类内的成员变量地址的图片,通过子线程计算出地址然后发送给主线程。形成类似定格动画的效果。但是我即使是使用的子线程让然会卡顿。前5秒左右还是正常的,之后就会越来越卡顿,希望各位帮我看看什么问题

//子线程
#include "plantthread.h"
#include <QTimer>
#include <QDebug>
#include <QPixmap>

plantThread::plantThread()
{

}

void plantThread::run()
{
    this->timer = new QTimer();
    connect(timer,&QTimer::timeout,this,&plantThread::startWork);
    this->timer->start(60);
    exec();
}

//void plantThread::startThread()
//{
//    this->thread->start();
//}

void plantThread::startWork()
{
           QString add = ":/res/plants/sunflower/sunflower";
           add = add + QString::number(this->picNum) + ".png";
           QPixmap pix(add);
           emit changePic(pix);
           this->picNum++;
           if (this->picNum == 28)
           {
               this->picNum = 1;
           }
           qDebug()<<add;
}
//主线程
plantThread * thread = new plantThread;
    connect(thread,&plantThread::changePic,this,[=](QPixmap pix){
        this->cartoonFileName = pix;
    });
    thread->start();
    this->update();
//paint函数内部
        painter->drawPixmap(0,0,cartoonFileName)

【以下回答由 GPT 生成】

问题出在每次绘制图片时都需要读取图片文件的内容,这会导致IO操作的延迟,从而引起卡顿。为了解决这个问题,可以将图片预加载到内存中,然后直接从内存中获取图片,这样可以减少IO操作的时间。

以下是一种可能的解决方案:

  1. 在主线程中,先加载所有的图片文件,并将其存储在一个QList<QPixmap>中。可以在主线程的初始化阶段进行这个操作。例如:
QList<QPixmap> pixmapList;
for (int i = 1; i <= 28; i++) {
    QString add = ":/res/plants/sunflower/sunflower" + QString::number(i) + ".png";
    QPixmap pix(add);
    pixmapList.append(pix);
}
  1. 在子线程中,将图片的索引作为参数发送给主线程,而不是直接发送QPixmap对象。子线程中的代码修改如下:
void plantThread::startWork()
{
    emit changeIndex(this->picNum);
    this->picNum++;
    if (this->picNum == 28)
    {
        this->picNum = 1;
    }
    qDebug() << add;
}
  1. 在主线程中,接收到索引后,直接使用预加载的图片列表来获取对应的图片,而不是从文件中读取。主线程中的代码修改如下:
int cartoonIndex;
connect(thread, &plantThread::changeIndex, this, [this, &cartoonIndex] (int index) {
    cartoonIndex = index;
});
//...
painter->drawPixmap(0, 0, pixmapList[cartoonIndex]);

通过以上优化,可以避免每次绘制图片时的IO操作,可能会显著提高性能并解决卡顿问题。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^