从线程中分离对象

Posted

技术标签:

【中文标题】从线程中分离对象【英文标题】:Detach object from thread 【发布时间】:2013-04-17 06:41:31 【问题描述】:

简单的问题:是否可以从 QThread 中分离 QObject 以将其移至主线程?

我使用以下代码:

QThread *thread = new QThread();

MyObject *object = new MyObject();

object->moveToThread(thread);

thread->start();

在我想将MyObject 实例移动到主线程之后的某个地方。

object->moveToThread(QApplication::instance()->thread());

我有以下错误:QObject::moveToThread: Current thread (0x00000001) is not the object's thread (0x00000002). Cannot move to target thread (0x00000003)

谢谢

【问题讨论】:

【参考方案1】:

由于official doc says、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 对象现在是否真的在主线程中。

但我真的不明白你为什么需要这个。

【讨论】:

好的,但是怎么做呢?只是用新线程调用moveToThread 在您的示例中执行类似操作,但首先启动线程,然后调用 moveToThread 方法。 我更新了问题。我尝试将对象移回主线程。但结果相同...... @hank:谢谢你的例子。我同意。我已经尝试过了,但它失败了。问题来自moveToThread(qApp-&gt;thread()); 行。同样的错误信息...无论如何,如果您想了解我的需求,请查看this post。 @Maxbester 上面的代码对我来说很好,我没有错误。我认为您可以在每个连接函数中指定连接类型:Qt::QueuedConnection

以上是关于从线程中分离对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从 R 中的特定包中分离所有对象和方法? [复制]

std::thread 线程在对象中分离,它何时终止?

从 Access 应用程序中分离出组件 VB

如何在 Windows 窗体中分离 UI 线程和进程线程

如何强制从另一个 SSH 会话中分离屏幕?

如何从数组列表中分离数据并将其显示到列表视图中?