Move方式创建线程
这种方法通过将工作逻辑封装在一个 QObject 派生类中,并将其移动到 QThread 对象中执行。通过信号和槽实现线程间通信。移动过后任务类归属于QThread子线程。
QObject移动到线程的方法
cpp
void QObject::moveToThread(QThread *targetThread)
优点:
- 更加符合 Qt 的信号槽机制。
- 更容易管理线程生命周期。
- 提高代码的可维护性和可扩展性。
我们先实现一个自定义的Worker任务类,使其继承自QObject,但是要注意,类的声明一定要包含Q_OBJECT宏
cpp
class Worker : public QObject
{
Q_OBJECT
public:
//显示构造worker类
explicit Worker(QObject *parent = nullptr);
signals:
public slots:
//响应线程started信号
void doWork();
signals:
//任务完成后发出这个信号
void finished();
};
实现构造函数
cpp
Worker::Worker(QObject *parent) : QObject(parent)
{
}
实现开始任务的槽函数
cpp
void Worker::doWork()
{
qDebug() << "工作线程开始:" << QThread::currentThreadId();
for(int i = 0; i < 5; i++){
qDebug() << "计数:" << i;
QThread::sleep(1); // 模拟耗时操作
}
//发送结束信号
emit finished();
qDebug() << "工作线程结束:" << QThread::currentThreadId();
}
在主函数中创建一个线程,并且将这个任务类移交给线程
注意
被移交的类一定不能有父窗口
cpp
//创建一个新的线程
QThread* worker_thread = new QThread();
//创建任务类
Worker* worker = new Worker();
//将worker移动到线程里
worker->moveToThread(worker_thread);
因为我们要通过线程的信号通知任务类开始工作,以及任务类要通过完成信号通知线程退出等,这里先列举几个信号
QThread线程开始信号,该信号在调用QThread的start()方法后由QThread发出
cpp
[signal] void QThread::started()
QThread线程结束信号,在线程调用quit()或者正常退出时发出这个信号
cpp
[signal] void QThread::finished()
我们先捕获线程的开始信号, 因为连接信号不是在QObject类里,所以显示调用QObject作用域连接
cpp
//连接线程开始信号
QObject::connect(worker_thread,&QThread::started,worker,&Worker::doWork);
所有QObject都有一个deleteLater槽函数
cpp
[slot] void QObject::deleteLater()
捕获线程退出信号,连接线程自己的deleteLater槽函数,
cpp
//连接线程退出信号和回收槽函数
QObject::connect(worker_thread, &QThread::finished, worker_thread, &QThread::deleteLater);
连接worker退出信号和回收槽函数
cpp
//连接worker退出信号和回收槽函数
QObject::connect(worker,&Worker::finished,worker,&Worker::deleteLater);
启动线程
cpp
//启动线程
worker_thread->start();
完整版代码
cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建一个新的线程
QThread* worker_thread = new QThread();
//创建任务类
Worker* worker = new Worker();
//将worker移动到线程里
worker->moveToThread(worker_thread);
//连接线程开始信号
QObject::connect(worker_thread,&QThread::started,worker,&Worker::doWork);
//连接任务类结束信号,调用线程退出信号
QObject::connect(worker,&Worker::finished, worker_thread, &QThread::quit);
//连接线程退出信号和回收槽函数
QObject::connect(worker_thread, &QThread::finished, worker_thread, &QThread::deleteLater);
//连接worker退出信号和回收槽函数
QObject::connect(worker,&Worker::finished,worker,&Worker::deleteLater);
//启动线程
worker_thread->start();
MainWindow mainwindow;
mainwindow.show();
//等待任务执行完成退出
return a.exec();
}
程序运行后,输出
bash
工作线程开始: 0x4124
计数: 0
计数: 1
计数: 2
计数: 3
计数: 4
工作线程结束: 0x4124
因为a.exec()还在等待其他事件处理,所以主线程不会退出。