PDA

View Full Version : QThread: Thread does not leave event loop on quit() using Queued signals, why ?



franku
1st December 2010, 11:15
I have a small worker thread:



class ReloadDirectoryThread : public QThread
{
Q_OBJECT
public:
ReloadDirectoryThread()
: QThread() {
};

~ReloadDirectoryThread() {
};

void run() {
exec();
};

public slots:
void importImage(int row, QString filePath);
signals:
void imageImported(int row, QIcon* icon);
};


Its task is to open Images pointed to by filePath, convert them into a QIcon and emit each new Icon:



void ReloadDirectoryThread::importImage(int row, QString filePath)
{
QIcon* icon = new QIcon(QPixmap(filePath));
emit imageImported(row, icon);
}


The thread will be started from the main-application thread:



{ ...
reloadDirectoryThread = new ReloadDirectoryThread;

connect(this, SIGNAL(importImage(int,QString)),
reloadDirectoryThread, SLOT(importImage(int,QString)), Qt::QueuedConnection);

connect(reloadDirectoryThread, SIGNAL(imageImported(int,QIcon*)),
this, SLOT(imageImported(int,QIcon*)), Qt::QueuedConnection);

reloadDirectoryThread->moveToThread(reloadDirectoryThread);
reloadDirectoryThread->start();
...}



The Thread should be shut down when closing the app:



{...
reloadDirectoryThread->quit();
reloadDirectoryThread->wait(3000);
delete reloadDirectoryThread;
...}


This will tell the thread to quit its eventLoop and waits at most 3 seconds for the thread to finish. At this time all "importImage"-signals are already posted into the event queue.

My problem is that the worker-thread always completes all messages (what in fact lasts more than three seconds) until the Thread Object can be deleted safely.

Any ideas what's going wrong ? Why does the thread not stop executing events from the eventqueue when calling quit() ?

.. frank

wysota
1st December 2010, 11:19
Most likely the event loop will quit only when all already scheduled events are processed. And since you are sending multiple signals from another thread before you call quit() then all those signals will be handled first and only then the loop will exit.

franku
1st December 2010, 11:33
I see. So I will have a flag to omit the work on a shutdown.


void ReloadDirectoryThread::importImage(int row, QString filePath)
{
if(!_shutdown) {
QIcon* icon = new QIcon(QPixmap(filePath));
emit imageImported(row, icon);
}
}


I thought there was a mistake. Thanks.