Reputation: 2533
Simple question: is it possible to detach a QObject from a QThread in order to move it to the main thread?
I use the following code:
QThread *thread = new QThread();
MyObject *object = new MyObject();
object->moveToThread(thread);
thread->start();
And somewhere after I want to move the MyObject
instance to the main thread.
object->moveToThread(QApplication::instance()->thread());
I have the following error: QObject::moveToThread: Current thread (0x00000001) is not the object's thread (0x00000002). Cannot move to target thread (0x00000003)
.
Thanks
Upvotes: 2
Views: 4560
Reputation: 9883
As the official doc says, moveToThread
function can not "pull" an object from another thread, it "pushes" an object to another thread.
That's why if you want to change the thread affinity of your object, you should do it in the current object's thread.
I've added a simple example.
Here's Worker
class:
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
signals:
void done();
public slots:
void doWork();
void checkThread();
private:
bool isMainThread();
};
Worker::Worker(QObject *parent) :
QObject(parent)
{
qDebug() << __PRETTY_FUNCTION__
<< QThread::currentThread()
<< isMainThread();
}
void Worker::doWork()
{
qDebug() << __PRETTY_FUNCTION__
<< QThread::currentThread()
<< isMainThread();
qDebug() << __PRETTY_FUNCTION__ << "Work is done";
moveToThread(qApp->thread());
emit done();
}
void Worker::checkThread()
{
qDebug() << __PRETTY_FUNCTION__
<< QThread::currentThread()
<< isMainThread();
}
bool Worker::isMainThread()
{
return QThread::currentThread() == qApp->thread();
}
We create a Worker
object, a QThread
object and connect them with each other:
QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
QObject::connect(worker, SIGNAL(done()), thread, SLOT(quit()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(checkThread()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
That's what we got in the application output:
Worker::Worker(QObject*) QThread(0x1034680) true
void Worker::doWork() QThread(0x1224970) false
void Worker::doWork() Work is done
void Worker::checkThread() QThread(0x1034680) true
A Worker
object is being created in the main application thread, then it does its work in a new thread. After job is done, it sends done()
signal and moves itself back to the main thread. After a thread is finished we check that our Worker
object is now really in the main thread again.
But really I don't understand why you may need this.
Upvotes: 3