PDA

View Full Version : qthread - eventloop - in non-qt app



ctarsoaga
23rd January 2015, 09:24
Hi

I try to use a simple thread


class MyThread : public QThread
{
Q_OBJECT
private:
virtual void run()
{
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout), this, SLOT(onTimer()));
timer.start(1000);
QThread::exec();
}
private slots:
void onTimer() {....}
};

in an application that does not have a QCoreApplication event loop in the main thread, e.g.


void main()
{
QCoreApplication app;

//no app.exec() here, we use our custom loop

forever()... {}
}

I start an instance of MyThread but I never receive any timer events.
I am not able to add app.exec() in the main thread so I added a QEventLoop somewhere and then I started to receive my timer events.
But I don't understand what is going on: I expected to have the timer events working since I do have an event loop inside my thread.

I cannot check now, but it just came to me that maybe the onTimer() slot gets called on a different thread.
Can that be the problem?

Can somebody please explain?
Thanks a lot

yeye_olive
23rd January 2015, 10:52
The line

QObject::connect(&timer, SIGNAL(timeout), this, SLOT(onTimer()));
connects the timer's signal to a slot of the QThread object itself. The QThread object lives in the main thread, not in the thread it manages. Therefore the connection behaves as a queued connection, and the slot will only be executed if you start the event loop in the main thread.

You could instead move the slot to a new object, e.g. MyObject, that lives in the worker thread, e.g.:

class MyObject : public QObject {
Q_OBJECT
/* ... */
public slots:
void onTimer();
}

/* ... */

virtual void MyThread::run() {
QTimer timer;
MyObject myObject;
QObject::connect(&timer, SIGNAL(timeout), &myObject, SLOT(onTimer()));
timer.start(1000);
QThread::exec();
}