QImage和QPixmap都是可以用于显示图片的,但是有一些不同。比如说QPixmap是与硬件关联的,而QImage是硬件独立的。硬件关联的一个特点是不可以跨线程访问。就是说QImage可以单独的用线程加载,然后在另一个线程展示,而QPixmap不可以。
对这个硬件关联我没有这个概念,体会不深,但是在做图片多线程加载的时候,使用QPixmap吃了很多苦头。
1、QPixmap不可以使用在子线程中加载图片。
准确的说,使用在子线程加载图片也是可以的,但是调试的时候会报“segmentation fault”(段错误),原因可能就是刚才说的硬件关联等问题。
不管是使用引用初始化,还是用new,都是徒劳的。
如果忽略调试时的问题,正常跑起来也是没问题的。
2、用QImage代替QPixmap
历经尝试n多种方法,才发现用QImage代替QPixmap在线程中加载,可以解决上述“segmentation fault”。从线程中加载了图片之后,把QImage引用通过信号传递给主线程。
QImage image;
image.load(path);
QThread::msleep(500);
emit onImgLoadSignal(image);
3、如果QImage用指针将会删除不掉
一个想法,QImage想用指针来做,这样在接收到了之后,使用结束了,可以删除掉。但是实际上删除不掉:
(之所以想要手动删除,看第四点)
QPixmap pixmap = QPixmap::fromImage(*image);
pixmap.scaled(picSize,Qt::KeepAspectRatio);
buttonImg->setIcon(pixmap);
if(image)
{
qDebug()<<"delete image";
delete image;
if(image)
qDebug()<<"delete no succ!";// 一直都输出这个!
}else
{
qDebug()<<"image no exists";
}
这样做的结果是很快内存就不够用了。
4、QPixmap::fromImage有bug
如果这样进行内存QImage和QPixmap的转化,会内存泄露,我也不清楚是QImage泄露还是QPixmap泄露,这可能是qt的bug:
QPixmap pixmap = QPixmap::fromImage(image);
pixmap.scaled(picSize,Qt::KeepAspectRatio);
buttonImg->setIcon(pixmap);
5、正确的进行QImage和QPixmap的转化
QPixmap pixmap = QPixmap::fromImage(image.scaled(picSize));
buttonImg->setIcon(pixmap);
奇怪的是这样使用fromImage函数竟然不会内存泄露!
版权声明:本文为wzj0808原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。