当前位置: 首页 > news >正文

51、Move方式创建线程---------多线程

Move方式创建线程

这种方法通过将工作逻辑封装在一个 QObject 派生类中,并将其移动到 QThread 对象中执行。通过信号和槽实现线程间通信。移动过后任务类归属于QThread子线程。
QObject移动到线程的方法

void QObject::moveToThread(QThread *targetThread)

优点:

  • 更加符合 Qt 的信号槽机制。
  • 更容易管理线程生命周期。
  • 提高代码的可维护性和可扩展性。

我们先实现一个自定义的Worker任务类,使其继承自QObject,但是要注意,类的声明一定要包含Q_OBJECT宏

class Worker : public QObject { Q_OBJECT public: //显示构造worker类 explicit Worker(QObject *parent = nullptr); signals: public slots: //响应线程started信号 void doWork(); signals: //任务完成后发出这个信号 void finished(); };

实现构造函数

Worker::Worker(QObject *parent) : QObject(parent) { }

实现开始任务的槽函数

void Worker::doWork() { qDebug() << "工作线程开始:" << QThread::currentThreadId(); for(int i = 0; i < 5; i++){ qDebug() << "计数:" << i; QThread::sleep(1); // 模拟耗时操作 } //发送结束信号 emit finished(); qDebug() << "工作线程结束:" << QThread::currentThreadId(); }

在主函数中创建一个线程,并且将这个任务类移交给线程

注意

被移交的类一定不能有父窗口

//创建一个新的线程 QThread* worker_thread = new QThread(); //创建任务类 Worker* worker = new Worker(); //将worker移动到线程里 worker->moveToThread(worker_thread);

因为我们要通过线程的信号通知任务类开始工作,以及任务类要通过完成信号通知线程退出等,这里先列举几个信号

QThread线程开始信号,该信号在调用QThread的start()方法后由QThread发出

[signal] void QThread::started()

QThread线程结束信号,在线程调用quit()或者正常退出时发出这个信号

[signal] void QThread::finished()

我们先捕获线程的开始信号, 因为连接信号不是在QObject类里,所以显示调用QObject作用域连接

//连接线程开始信号 QObject::connect(worker_thread,&QThread::started,worker,&Worker::doWork);

所有QObject都有一个deleteLater槽函数

[slot] void QObject::deleteLater()

捕获线程退出信号,连接线程自己的deleteLater槽函数,

//连接线程退出信号和回收槽函数 QObject::connect(worker_thread, &QThread::finished, worker_thread, &QThread::deleteLater);

连接worker退出信号和回收槽函数

//连接worker退出信号和回收槽函数 QObject::connect(worker,&Worker::finished,worker,&Worker::deleteLater);

启动线程

//启动线程 worker_thread->start();

完整版代码

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

程序运行后,输出

工作线程开始: 0x4124 计数: 0 计数: 1 计数: 2 计数: 3 计数: 4 工作线程结束: 0x4124

因为a.exec()还在等待其他事件处理,所以主线程不会退出。

http://www.jsqmd.com/news/610757/

相关文章:

  • 植物人工培育环境控制系统
  • Java AI - LangChain4j完整指南:核心组件解析+Ollama/百炼集成+实战案例 【含代码解析及代码仓库】
  • OpenClaw安全沙盒:基于SecGPT-14B的恶意代码分析自动化
  • 毕业之家使用教程:5步搞定毕业论文(附详细操作截图)
  • Linux系统目录结构与常用命令详解
  • 清关资料要求变细之后店铺稳定性为什么更依赖流程统一
  • GitHub 批量上传文件问题及解决方法
  • 告别轮询!用STM32CubeMX给STM32F030配置ADC多通道+DMA,实测代码分享
  • OpenClaw+Qwen3-14B镜像测评:Token消耗与任务成功率实测
  • 华为交换机DHCP Snooping防私接实战:从基础配置到Option82高级应用
  • 别再对齐口径了,对不齐的从来不是口径
  • 基于单片机的电子血压计(有完整资料)
  • 微电网主从控制孤岛运行与并网平滑切换策略研究(含VF、PQ控制及常见分布式发电问题归纳)
  • 线性电源芯片发热问题与开关电源选型指南
  • 新能源高速齿轮传动系统NVH开发、仿真及测试电子资料 适合机械、汽车、新能源行业工程师学习参考的资料,内容包括NVH开发基础、试验分析、模型建立、仿真方法、测试验证等
  • 电商运营自动化:OpenClaw+Phi-3-vision实现竞品图文分析
  • OpenClaw+千问3.5-9B智能监控:服务器异常自动报警
  • Ubuntu 18.04下500G硬盘如何部署Bitcoin全节点?实测避坑指南
  • OpenClaw浏览器自动化:gemma-3-12b-it操控Chrome完成信息采集
  • Kotlin Android Extensions插件弃用后,如何优雅解决act_main控件爆红问题?
  • 食品品牌想“一路狂飙”?福建远见品牌策划:全国性服务加持大单品策略,解锁增长“密码”
  • STM32 LWIP网络异常检测:三种实用方法对比与实现
  • Selenium IDE录制脚本操作记录
  • BarTender标签打印进阶:C#调用API实现动态数据填充(源码分享)
  • 每日两道力扣,day6
  • OpenClaw安全实践:百川2-13B-4bits模型+本地化处理敏感数据方案
  • 当神通数据库遇上MySQL:一个PowerDesigner逆向工程失败后的手动迁移实战
  • 【.NET 9边缘部署终极指南】:覆盖ARM64容器化、离线签名、资源精简至<28MB的7大实战验证策略
  • C语言:猜数字游戏
  • 袁永福 电子病历,医疗信息化蕴