1.QPixmap::loadFromData导致卡顿
由于项目中需要从网络上获取图片资源,这里用到的方法是QPixmap::loadFromData
方法 然后将QPixmap
通过setPixmap
设置到QLabel中,起初直接在GUI线程中执行着一段代码,但是发现,一旦开始获取网络资源,就会出现无响应现象,刚开始还以为是读写造成的,后来通过调试,发现这一步需要消耗大量的时间,最后 我将这个转换过程写到一个子线程中,将QByteArray
转换成QPixmap
然后通过信号发送出去,GUI线程接收到信号就可以直接操作QPixmap
到QLabel
中。
1.1 QPixmap不能在子线程中操作,会出现内存错误
通过查阅文档发现, QPixmap
跟硬件有关的,专门用于绘制的,因此无法在子线程中操作,图片资源的读写大多数通过QImage
来完成,因此上述方法会报错,转换了思路,我们将QImage
作为数据进行信号传递,但仍会报内存错误。查阅百度得知,需要进行一次scaled
操作,具体原因未知,代码如下:
if(image.isNull())
{
return;
}
// 注意这里的scaled必须在image上完成,在Pixmap上完成也会报错
QPixmap mPixmap = QPixmap::fromImage(image.scaled(ui->itemIconLabel->width(), ui->itemIconLabel->height()));
ui->itemIconLabel->setPixmap(mPixmap);
2.错误的槽函数绑定导致错误
上述操完成之后,程序的卡顿现象确实少了不少,但是程序输出上面会出现这样一行字QThread::start: Failed to create thread (xxxxx)
出现这样的情况,我记录了子线程调用的次数,结果输出大吃一惊:当前图片次数 36100
,结果输出了36000多个线程,结果可想而知,解决这个问题的方法就是减少线程数,知道了肯定是线程调用次数太多了。
通过分析,发现槽函数绑定的问题。一开始我将connect
写在了一个槽函数中,这个槽函数是处理网页请求得到的数据的,一个网页基本上有20-30条数据,因此每次执行这个槽函数,都会connect
一次,而且是递归进行的。所以叠加connect
次数才会出现这个数。
// 原程序代码
void MainWidget::addHomeItem(QWidget *listWidget, HomeItem *homeItem)
{
movieItem* homeMovieItem = new movieItem(this);
homeMovieItem->homeItem = homeItem;
homeMovieItem->setText(homeItem->itemTitle);
homeMovieItem->setNumber(homeItem->itemNumber);
homeMovieItem->setTime(homeItem->itemTime);
listWidget->layout()->addWidget(homeMovieItem);
void *widgetAttribute = (void *)homeMovieItem;
this->homeImgRequest->get(widgetAttribute, QUrl(homeItem->imgPath), true);
// 后来我将这个connect函数放在了构造函数中,连接数减少到了正常
connect(this->homeImgRequest, SIGNAL(dataRequested(void*,QByteArray)), this, SLOT(onReceivedItemImg(void*,QByteArray)));
}