C++ QThread moveToThread不';行不通

C++ QThread moveToThread不';行不通,c++,multithreading,qt,qthread,C++,Multithreading,Qt,Qthread,我有一个GUI的主线程,在其中运行MainWindow对象, 在其构造函数中,我创建了一个新的worker对象和一个QThread对象,然后我将worker移动到线程中,问题是当打印它们的ID时,它们是相同的: main window.cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { std::cout<<"MAIN_ID "&

我有一个GUI的主线程,在其中运行
MainWindow
对象, 在其构造函数中,我创建了一个新的worker对象和一个
QThread
对象,然后我将worker移动到线程中,问题是当打印它们的ID时,它们是相同的:

main window.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    std::cout<<"MAIN_ID "<< QThread::currentThreadId()<<std::endl;
    QThread *t_pc = new QThread;
    worker *pc_w;
    pc_w = new pc_worker();
    pc_w->moveToThread(t_pc);
    t_pc->start();
    pc_w->initialize();
    // ...
}
worker::worker(QObject *parent) : QObject(parent) {

}

void worker::initialize() {
    std::cout << "INITIALIZE " << QThread::currentThreadId() << std::endl;
}
怎么了?

尝试使用而不是直接调用
pc\u w->initialize()
,例如:

QMetaObject::invokeMethod(pc_w, "initialize", Qt::QueuedConnection);

在这种情况下,
initialize()
方法应该是SLOT或SIGNAL

回答:
moveToThread
确实可以工作,只是没有按照您预期的方式工作

调用
pc\u w->moveToThread(t\u pc)
后,您希望
pc\u w
的所有成员函数现在都在
t\u pc
中调用。但是,这不是
moveToThread()
所做的

moveToThread()
的目的是更改
QObject
的“线程关联”,或者换句话说,更改对象所在的线程在基本级别上,它提供给您的一切只是保证通过
Qt::QueuedConnection
连接到任何信号的所有对象插槽都将在该特定线程中被调用(运行)

成员函数仍然在调用它们的线程中运行。在本例中,您从GUI线程调用
initialize()
,因此
QThread::currentThreadId()
为您提供该线程的id

我真的建议阅读官方文档和线程事件循环

QThread* thread = new QThread;
Worker* worker = new Worker;

// Uses Qt::AutoConnection (default)
// which will be transalted into Qt::QueuedConnection
QObject::connect(thread, &QThread::started, worker, &Worker::initialize);

std::cout<<"MAIN_ID "<< QThread::currentThreadId()<<std::endl;

worker->moveToThread(thread);
thread->start();


提出的解决方案trivelt人为地将“call
initialize()
”事件放入线程事件循环中,从而达到相同的效果。但是,它不执行任何编译时检查(“initialize”被指定为字符串)。

但是,当通过connect SLOT/SIGNAL调用worker类时,打印的ID是不同的。当您直接调用函数时,它将在调用它的线程中运行。Define initialize()作为插槽并从MainWindow发出信号。像这样连接它们:连接(这个,信号(信号初始化()),pc\U w,插槽(初始化()),Qt::QueuedConnection);
QThread* thread = new QThread;
Worker* worker = new Worker;

// Uses Qt::AutoConnection (default)
// which will be transalted into Qt::QueuedConnection
QObject::connect(thread, &QThread::started, worker, &Worker::initialize);

std::cout<<"MAIN_ID "<< QThread::currentThreadId()<<std::endl;

worker->moveToThread(thread);
thread->start();
MAIN_ID 0000000000003E5C
INITIALIZE 0000000000003DAC