将对象从QThread更改为主GUI线程

时间:2018-05-17 13:11:18

标签: c++ multithreading qt qthread

我有一个Qt GUI应用程序,它包含一些类和一个main。对于计算量大的写操作之一,我创建了一个QThread作为类成员。像这样:

//class members
std::unique_ptr<QThread> m_savingThread;
std::unique_ptr<DiffClass> m_controller;

connect(this, &SomeClass::saveAll, m_controller.get(), &DiffClass::saveToAll, Qt::QueuedConnection);    
connect(m_controller.get(), &DiffClass::done, m_savingThread.get(), &QThread::quit);

void SomeClass::saveToFile()
{
    //Saving thread
    qDebug() << "From main thread:" << QThread::currentThreadId();

    m_controller->moveToThread(m_savingThread.get());
    m_savingThread->start();

    qRegisterMetaType<std::string>("std::string");
    emit saveAll(someString);
 }

上面的代码工作正常。但是,一旦保存操作完成,我需要将m_controller对象返回到主GUI线程。我能找到类似的东西 here。简而言之,它指出,QThread只能推动&#34;将对象转换为线程,我需要将它再次推送到当前工作线程的主线程中。

void DiffClass::saveToAll(someString)
{
    qDebug() << "From worker thread:" << QThread::currentThreadId();
    /*saving operation*/
    moveToThread(QApplication::instance()->thread()); //Error QCoreApplication has no member thread()
    emit done();
}

有没有办法将对象的亲和力更改回主线程?

编辑1:我的connectsaveToAll是QueuedConnection。

1 个答案:

答案 0 :(得分:0)

首先,为什么要来回切换线程关联?这似乎没有实际意义。

除此之外,应该可以将其更改为另一个威胁,条件是该对象没有父对象,并且从当前关联线程调用moveToThread()

您可以使用QMetaObject::invokeMethod()与任何线程中指定的Qt::QueuedConnection来安排从当前关联线程执行插槽,这将从正确的线程更改为您作为参数传递的任何线程。< / p>

但是看看你如何尝试从类内部改变它,只要通过信号/槽机制调用saveToAll()(而不是直接来自任何线程),它应该按预期工作。 / p>

//Error QCoreApplication has no member thread()

根据文档,肯定会这样做。