Solved ASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273
-
Hi, friend. I opened a lot of images at once. and then,passed these image paths to some subclass
QRunnable
to read data. like below snippet code.for(int i=0; i<ltfilesPath.size(); i++){ task = new CreateItemTask(ltfilesPath[i]); connect(task,&CreateItemTask::SigCreateItemTaskFinished, this,&MainWindow::StCreateItemTaskFinished); _threadPool->start(task); }
about my
CreateItemTask
class, like below code snippet:TEITEMTASK_H #define CREATEITEMTASK_H #include <QtCore/QRunnable> #include <QtCore/QObject> class CreateItemTask : public QObject, public QRunnable { Q_OBJECT public: CreateItemTask(const QString &filePath,QObject *parent = Q_NULLPTR); ~CreateItemTask(); void run() override; signals: void SigCreateItemTaskFinished(void* item); private: QString _filePath; }; #endif // CREATEITEMTASK_H
#include "itemtask.h" /** some include here ... */ CreateItemTask::CreateItemTask(const QString &filePath, QObject *parent) :QObject(parent),QRunnable() { _filePath = filePath; setAutoDelete(true); } CreateItemTask::~CreateItemTask() { } void CreateItemTask::run() { /** some declare here */ if(!ReadPixmap(_filePath,pixmap)){ /// this function code at below. return; } pItem = new QListWidgetItem; /** iterm set some data at here... */ /** some code here.... */ emit SigCreateItemTaskFinished((void*)pItem); }
ReadPixmap
Function.bool ReadPixmap(QString qsFilePath, QPixmap &pixmap) { /** some declare here... */ if(!pixmap.load(qsFilePath)){ ///< Note here... reader.setFileName(qsFilePath); reader.setDecideFormatFromContent(true); if(!reader.canRead()){ return false; } image = reader.read(); if(image.isNull()){ return false; } pixmap = QPixmap::fromImage(image); if(pixmap.isNull()){ return false; } } return true; }
sometime,
pixmap.load(qsFilePath)
some image can read crashed, and putoutASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273
What's wrong i did? and How to work it out?
-
@joeQ said in ASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273:
if(!ReadPixmap(_filePath,pixmap))
Where is pixmap declared? Did you check all the images you're trying to load? Maybe some of them are broken?
-
You can't use pixmaps from different threads, you need to switch to
QImage
when doing multithreading. -
Thank you very much.
I modified the function to
bool ReadPixmap(QString qsFilePath, QPixmap &pixmap) { /** some declare at here */ reader.setFileName(qsFilePath); reader.setDecideFormatFromContent(true); if(!reader.canRead()){ return false; } image = reader.read(); if(image.isNull()){ return false; } pixmap = QPixmap::fromImage(image); if(pixmap.isNull()){ return false; } return true;
It worked.
-
You still have a problem as you're creating, accessing and modifying widgets and pixmaps from different threads.
QWidget
andQPixmap
are not reentrant, meaning you can create and access them only from the GUI thread.pItem = new QListWidgetItem;
and
pixmap = QPixmap::fromImage(image);
are the offending lines. You need to modify everything in such a way that the widget creation and the pixmap conversion are done in the GUI thread; namely inside
MainWindow::StCreateItemTaskFinished
, not in the runnable's implementation. -
Yes, that friend above is right