简体   繁体   English

将对象的亲和力从QThread更改为GUI主线程

[英]Change affinity of an Object from a QThread to Main GUI Thread

I have a Qt GUI application which contains some classes and a main. 我有一个Qt GUI应用程序,其中包含一些类和一个main。 For one of the computationally heavy writing operation i created aa QThread as a class member. 对于其中一项计算量很大的编写操作,我创建了一个QThread作为类成员。 Something like this: 像这样:

//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);
 }

The above code works fine. 上面的代码工作正常。 But i need the m_controller object back to the main GUI thread once the saving operation is finished. 但是一旦保存操作完成,我需要将m_controller对象返回到主GUI线程。 I could find something similar here . 在这里可以找到类似的东西 Briefly, it states that since QThread can only "push" the object into a thread, i need to push it again into the main thread from the current worker thread. 简要地说,它声明由于QThread只能将对象“推”入线程,因此我需要将其从当前工作线程再次推入主线程。

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

Is there a way to change the affinity of the object back to the main thread? 有没有一种方法可以将对象的亲和力更改回主线程?

EDIT 1: My connect to saveToAll is a QueuedConnection. 编辑1:我对saveToAll connect是一个QueuedConnection。

First and foremost, why would you want to switch thread affinity back and forth? 首先,为什么要来回切换线程亲和力? There doesn't seem to be a practical side to this. 似乎没有实际的一面。

Other than that, it should be possible to change it to another threat, the condition is that the object has no parent and the moveToThread() is invoked from the current affinity thread. 除此之外,应该有可能将其更改为另一种威胁,条件是该对象没有父对象,并且从当前关联线程调用moveToThread()

You can use QMetaObject::invokeMethod() with Qt::QueuedConnection specified from any thread to schedule a slot execution from the current affinity thread, which will change affinity from the right thread to whatever thread you pass as a parameter. 您可以将QMetaObject::invokeMethod()与从任何线程指定的Qt::QueuedConnection使用,以调度从当前亲和力线程执行的插槽执行,这将从正确的线程更改为您作为参数传递的任何线程的亲和力。

But seeing how you try to change it from inside the class, that should work as expected, as long as saveToAll() is invoked via the signal/slot mechanism (rather than directly from just about any thread). 但是,只要您通过信号/插槽机制(而不是直接从任何线程直接saveToAll()调用saveToAll()就可以看到如何尝试从类内部进行更改,这应该可以按预期工作。

//Error QCoreApplication has no member thread()

It most certainly does according to the documentation. 它当然可以根据文档进行操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM