正如官方文档所说,moveToThread
函数不能从另一个线程“拉”一个对象,它将一个对象“推”到另一个线程。
这就是为什么如果要更改对象的线程亲和性,应该在当前对象的线程中进行。
我添加了一个简单的示例。
这是Worker
课程:
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();
}
我们创建一个Worker
对象,一个QThread
对象并将它们相互连接:
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();
这就是我们在应用程序输出中得到的:
Worker::Worker(QObject*) QThread(0x1034680) true
void Worker::doWork() QThread(0x1224970) false
void Worker::doWork() Work is done
void Worker::checkThread() QThread(0x1034680) true
在主应用程序线程中创建一个Worker
对象,然后它在一个新线程中工作。工作完成后,它发送done()
信号并将自身移回主线程。线程完成后,我们再次检查我们的Worker
对象是否真的在主线程中。
但我真的不明白你为什么需要这个。