donelron
17th December 2015, 09:44
Dear all,
I am working with legacy code in a class AddTileStackToPixmapcacheWorker with header (much simplified example):
#ifndef AddTileStackToPixmapcacheWorkerQRunnableQRUNNABLE_ H__
#define AddTileStackToPixmapcacheWorkerQRunnableQRUNNABLE_ H__
#include <QObject>
#include <QRunnable>
#include <QGraphicsPixmapItem>
#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/io/png_io.hpp>
#include <boost/gil/image.hpp>
#include <set>
class AddTileStackToPixmapcacheWorker : public QObject, public QRunnable {
Q_OBJECT
public:
AddTileStackToPixmapcacheWorker (QString Filename);
~AddTileStackToPixmapcacheWorker ();
void run();
void LoadImagesFromHardDriveIntoVector();
bool LoadImageDataRgb8(QString fileNameRelative, QPixmap & ima);
private:
QString m_Filename;
};
#endif
and cpp:
#include "AddTileStackToPixmapcacheWorker.h"
#include <iostream>
#include <QDebug>
#include <QThread>
AddTileStackToPixmapcacheWorker::AddTileStackToPix mapcacheWorker (QString Filenames) :
m_Filename (Filenames)
{
}
AddTileStackToPixmapcacheWorker::~AddTileStackToPi xmapcacheWorker()
{
}
void AddTileStackToPixmapcacheWorker::run()
{
QPixmap ima;
bool b = LoadImageDataRgb8(m_Filename, ima);
}
bool AddTileStackToPixmapcacheWorker::LoadImageDataRgb8 ( QString fileNameRelative, QPixmap & ima )
{
if (fileNameRelative.size())
{
QString fileNameAbsolute = "D:/Sharing/MicroscopyImageData/falc_Nr2_13013792_2015.04.02-12.32.10/images/" + fileNameRelative;
const char * pChar;
//check ending for .jpg or .jpeg
if (fileNameAbsolute.endsWith(".jpg", Qt::CaseInsensitive) || fileNameAbsolute.endsWith(".jpeg", Qt::CaseInsensitive))
{
pChar = "JPG";
}
ima.load(fileNameAbsolute, pChar);
return true;
}
return false;
}
I use it like that:
#include "AddTileStackToPixmapcacheWorker.h"
void myThreadingExample()
{
std::vector<QString> vecStrings;
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_0_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_0_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_1_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_1_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_10_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_10_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_11_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_11_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_12_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_12_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_13_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_13_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_14_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_14_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_15_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_15_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_16_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_16_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_17_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_17_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_18_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_18_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_19_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_19_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_2_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_2_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_20_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_20_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_21_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_21_Index_0_orig.jpg"));
for (int i=0; i< vecStrings.size(); i++)
{
AddTileStackToPixmapcacheWorker *pAddTileStackToPixmapcacheWorker = new AddTileStackToPixmapcacheWorker(vecStrings[i]);
pAddTileStackToPixmapcacheWorker->setAutoDelete(true);
QThreadPool::globalInstance()->setExpiryTimeout(-1);
QThreadPool::globalInstance()->start(pAddTileStackToPixmapcacheWorker);
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
myThreadingExample();
return app.exec();
}
When I run this i get stuff like the following in the console:
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
and when I close my console window I get:
QObject::~QObject: Timers cannot be stopped from another thread
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
Once or twice (out of around 20 or 30 tries) it also crashed with some unhandled exception, but I don't remember what the exact error description was.
What am I doing wrong?
How else would I be able to load several images asynchronously?!?
I've tried to use only one "extra" thread for loading images, which is more stable, but for my use case is also much slower than the example in this post. So, to summarize: I am looking for either:
1) a way to fix my QRunnable example or
2) a different multithreaded approach that works
Any ideas?!? Many many thanks in advance!!!!!
I am working with legacy code in a class AddTileStackToPixmapcacheWorker with header (much simplified example):
#ifndef AddTileStackToPixmapcacheWorkerQRunnableQRUNNABLE_ H__
#define AddTileStackToPixmapcacheWorkerQRunnableQRUNNABLE_ H__
#include <QObject>
#include <QRunnable>
#include <QGraphicsPixmapItem>
#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/io/png_io.hpp>
#include <boost/gil/image.hpp>
#include <set>
class AddTileStackToPixmapcacheWorker : public QObject, public QRunnable {
Q_OBJECT
public:
AddTileStackToPixmapcacheWorker (QString Filename);
~AddTileStackToPixmapcacheWorker ();
void run();
void LoadImagesFromHardDriveIntoVector();
bool LoadImageDataRgb8(QString fileNameRelative, QPixmap & ima);
private:
QString m_Filename;
};
#endif
and cpp:
#include "AddTileStackToPixmapcacheWorker.h"
#include <iostream>
#include <QDebug>
#include <QThread>
AddTileStackToPixmapcacheWorker::AddTileStackToPix mapcacheWorker (QString Filenames) :
m_Filename (Filenames)
{
}
AddTileStackToPixmapcacheWorker::~AddTileStackToPi xmapcacheWorker()
{
}
void AddTileStackToPixmapcacheWorker::run()
{
QPixmap ima;
bool b = LoadImageDataRgb8(m_Filename, ima);
}
bool AddTileStackToPixmapcacheWorker::LoadImageDataRgb8 ( QString fileNameRelative, QPixmap & ima )
{
if (fileNameRelative.size())
{
QString fileNameAbsolute = "D:/Sharing/MicroscopyImageData/falc_Nr2_13013792_2015.04.02-12.32.10/images/" + fileNameRelative;
const char * pChar;
//check ending for .jpg or .jpeg
if (fileNameAbsolute.endsWith(".jpg", Qt::CaseInsensitive) || fileNameAbsolute.endsWith(".jpeg", Qt::CaseInsensitive))
{
pChar = "JPG";
}
ima.load(fileNameAbsolute, pChar);
return true;
}
return false;
}
I use it like that:
#include "AddTileStackToPixmapcacheWorker.h"
void myThreadingExample()
{
std::vector<QString> vecStrings;
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_0_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_0_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_1_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_1_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_10_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_10_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_11_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_11_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_12_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_12_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_13_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_13_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_14_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_14_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_15_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_15_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_16_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_16_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_17_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_17_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_18_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_18_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_19_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_19_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_2_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_2_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_20_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_20_Index_0_orig.jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_21_Index_0_ds(1).jpg"));
vecStrings.push_back(QString("img_Rev_1_Mag_2.5_Stack_21_Index_0_orig.jpg"));
for (int i=0; i< vecStrings.size(); i++)
{
AddTileStackToPixmapcacheWorker *pAddTileStackToPixmapcacheWorker = new AddTileStackToPixmapcacheWorker(vecStrings[i]);
pAddTileStackToPixmapcacheWorker->setAutoDelete(true);
QThreadPool::globalInstance()->setExpiryTimeout(-1);
QThreadPool::globalInstance()->start(pAddTileStackToPixmapcacheWorker);
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
myThreadingExample();
return app.exec();
}
When I run this i get stuff like the following in the console:
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
and when I close my console window I get:
QObject::~QObject: Timers cannot be stopped from another thread
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
QWaitCondition: Destroyed while threads are still waiting
Once or twice (out of around 20 or 30 tries) it also crashed with some unhandled exception, but I don't remember what the exact error description was.
What am I doing wrong?
How else would I be able to load several images asynchronously?!?
I've tried to use only one "extra" thread for loading images, which is more stable, but for my use case is also much slower than the example in this post. So, to summarize: I am looking for either:
1) a way to fix my QRunnable example or
2) a different multithreaded approach that works
Any ideas?!? Many many thanks in advance!!!!!