【问题标题】: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)

谢谢

【问题讨论】:

    标签: c++ qt qthread qobject


    【解决方案1】:

    由于official doc saysmoveToThread 函数不能从另一个线程“拉”一个对象,它会将一个对象“推”到另一个线程。

    这就是为什么如果要更改对象的线程亲和性,应该在当前对象的线程中进行。

    我添加了一个简单的例子。

    这里是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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 2019-11-09
    • 2021-09-15
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多