之前一直使用继承QThread的方法使用QT的多线程功能。这种方式下,只有run()函数内的程序段是真正运行于子线程中的。
为了搞明白moveToThread这种更“正确”方法的特点,专门做了一次实验
先贴代码。首先定义了一个测试用的类。类里面有一个槽函数,并且通过槽函数调用了一个私有方法
头文件中:
#ifndef THREAD_TEST_H
#define THREAD_TEST_H
#include <QObject>
#include "globle_define.h"
class thread_test : public QObject
{
Q_OBJECT
private:
void work_call(QString user);
public:
explicit thread_test(QObject *parent = nullptr);
~thread_test();
signals:
public slots:
void work(QString user);
};
#endif // THREAD_TEST_H
源文件中:
#include "thread_test.h"
#include <QThread>
thread_test::thread_test(QObject *parent) : QObject(parent)
{
qDebug()<<"setup ID:"<<QThread::currentThreadId();
}
thread_test::~thread_test()
{
qDebug()<<"kill ID:"<<QThread::currentThreadId();
}
void thread_test::work(QString user)
{
qDebug()<<user<<"work slot ID:"<<QThread::currentThreadId();
work_call(user);
}
void thread_test::work_call(QString user)
{
qDebug()<<user<<"work call ID:"<<QThread::currentThreadId();
}
接下来是测试方法:
qDebug()<<"主函数ID:"<<QThread::currentThreadId();
qDebug()<<"*********直接调用测试*********";
thread_test one(this);
one.work(tr("直接调用")); //这里测试是在主线程
qDebug()<<"*********先调用测试*********";
QThread thread_1(this);
thread_test two;
connect(this, SIGNAL(test(QString)), &two, SLOT(work(QString)));
emit test(tr("移入之前信号调用")); //这里测试是在主线程
two.moveToThread(&thread_1);
emit test(tr("移入之后信号调用")); //这里测试是在子线程
thread_1.start();
emit test(tr("start之后信号调用")); //这里测试是在子线程
Sleep(200);
disconnect(this, SIGNAL(test(QString)), &two, SLOT(work(QString)));
qDebug()<<"*********先Move测试*********";
QThread thread_2(this);
thread_test three;
three.moveToThread(&thread_2);
three.work(tr("移入之后直接调用")); //这里测试是在主线程
connect(this, SIGNAL(test(QString)), &three, SLOT(work(QString)));
emit test(tr("移入之后信号调用")); //这里测试是在子线程
thread_2.start();
emit test(tr("start之后信号调用")); //这里测试是在子线程
qDebug()<<"测试结束";
Sleep(5000);
最后是测试结果:
主函数ID: 0x3904
*********直接调用测试*********
setup ID: 0x3904
"直接调用" work slot ID: 0x3904
"直接调用" work call ID: 0x3904
*********先调用测试*********
setup ID: 0x3904
"移入之前信号调用" work slot ID: 0x3904
"移入之前信号调用" work call ID: 0x3904
"移入之后信号调用" work slot ID: 0x46b8
"移入之后信号调用" work call ID: 0x46b8
"start之后信号调用" work slot ID: 0x46b8
"start之后信号调用" work call ID: 0x46b8
*********先Move测试*********
setup ID: 0x3904
"移入之后直接调用" work slot ID: 0x3904
"移入之后直接调用" work call ID: 0x3904
测试结束
"移入之后信号调用" work slot ID: 0x4a18
"移入之后信号调用" work call ID: 0x4a18
"start之后信号调用" work slot ID: 0x4a18
"start之后信号调用" work call ID: 0x4a18
kill ID: 0x3904