In my application there's the main thread and a worker thread (QThread). From the main thread I'd like to invoke a method of my worker thread and have it run in the thread's context. I've tried using QMetaObject::invokeMethod and give it the QueuedConnection option but it's not working, I've also tried emitting signals from the main thread (which is connected to the worker thread's slot) but that also failed.
Here's a snippet of roughly what I tried:
class Worker : public QThread
{
Q_OBJECT
public:
Worker() { }
void run()
{
qDebug() << "new thread id " << QThread::currentThreadId();
exec();
}
public slots:
void doWork()
{
qDebug() << "executing thread id - " << QThread::currentThreadId();
}
};
Using the QMetaObject way:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
return a.exec();
}
Using the signal way:
class Dummy : public QObject
{
Q_OBJECT
public:
Dummy() { }
public slots:
void askWork() { emit work(); }
signals:
void work();
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
Dummy dummy;
QObject::connect(&dummy, SIGNAL(work()), &worker, SLOT(doWork()), Qt::QueuedConnection);
QTimer::singleShot(1000, &dummy, SLOT(askWork()));
return a.exec();
}
Both ways result in the main thread id being printed in the QThread's doWork.
Also, I thought of implementing a simple producer-consumer but if this works, is there any reason why not to do it this way?