QT之巧用对象充当信号接收者

备注:以下仅为演示不代表合理性,适合简单任务,逻辑简单、临时使用,可保持代码简洁,对于复杂的任务应创建一个专门的类来管理信号和线程池任务.

FileScanner类继承QObject和QRunnable,扫描指定目录下的文件获取文件列表,逐个发出fileFound信号;

FileHasher:继承QObject和QRunnable,计算文件的SHA1值,发出hashResult信号;

1、使用新建临时对象 

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 创建协调对象,处理信号QObject coordinator;// 启动文件扫描任务FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替换为实际目录QObject::connect(scanner, &FileScanner::fileFound, &coordinator, [&coordinator](const QString &filePath) {// 为每个找到的文件启动SHA1计算任务FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, &coordinator, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, &coordinator, []() {qDebug() << "Scanning finished.";// 可选:等待所有任务完成QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交扫描任务到全局线程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}
  • Qt 的信号槽机制要求信号的接收者是一个 QObject 或其派生类的实例。coordinator 是一个 QObject 实例,用于连接 FileScanner 和 FileHasher 发出的信号(如 fileFound 和 hashResult)。
  • 它充当信号的“中转站”,将任务的异步结果(例如找到的文件路径或计算的 SHA1 值)传递到处理逻辑中。
  • 它可以避免在 main 函数中创建额外的类或全局对象,保持代码简洁。

  • coordinator 是 main 函数的局部变量,其生命周期持续到程序退出。这足以处理所有信号,因为线程池任务的信号在事件循环中处理。

2、使用QCoreApplication对象

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 启动文件扫描任务FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替换为实际目录QObject::connect(scanner, &FileScanner::fileFound, &app, [&app](const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, &app, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, &app, []() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交扫描任务到全局线程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

QCoreApplication 是 Qt 应用程序的主对象,无需额外创建 QObject,app存在于整个程序生命周期,也可以直接用作信号槽连接的接收者,也适合信号槽逻辑简单、临时使用的场景。

缺点:语义上不够清晰,因为 QCoreApplication 的主要职责是管理应用程序,而不是任务协调,如果程序中有多个模块使用 app 处理信号,可能会导致信号槽逻辑混杂,这种方式并不推荐。

3、使用 lambda 表达式

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 启动文件扫描任务FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替换为实际目录QObject::connect(scanner, &FileScanner::fileFound, [=](const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, []() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交扫描任务到全局线程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

Qt 允许在信号连接中使用 lambda 表达式直接处理逻辑,无需显式的接收者对象。这种方式将信号处理逻辑直接嵌入 lambda 函数中。适合信号槽逻辑简单、临时使用的场景。

  • 代码更简洁,无需创建额外的 QObject,逻辑集中在 lambda 函数中,易于理解。
  • lambda 表达式无法像 QObject 那样方便地管理多个信号槽连接(例如断开连接),而且如果 lambda 中捕获了变量(如 [=]),特别需要注意捕获变量的生命周期。

4、使用静态函数或全局函数处理信号

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"// 静态函数处理信号
static void handleFileFound(const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);
}static void handleFinished() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";
}int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 启动文件扫描任务FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替换为实际目录QObject::connect(scanner, &FileScanner::fileFound, handleFileFound);QObject::connect(scanner, &FileScanner::finished, handleFinished);// 提交扫描任务到全局线程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

 定义静态函数 handleFileFound 和 handleFinished,直接连接到信号,不需要 QObject 接收者。但这种方式,静态函数无法方便地存储状态(如任务列表、结果收集),不易扩展,维护性较差,仅适合信号处理逻辑非常简单的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Transformer,多头注意力机制 隐式学习子空间划分

Transformer,多头注意力机制 隐式学习子空间划分 在Transformer中,多头注意力机制天然支持隐式学习子空间划分——每个注意力头可以专注于输入的不同方面(如语义、句法、位置关系等),从而隐式形成多个子空间。 一、核心思路:将多头注意力视为隐式子空间 原理 Transfo…

java基础(继承)

什么是继承 继承好处 提高代码的复用性 继承注意事项 权限修饰符 单继承、Object类 冲突&#xff1a; 方法重写 扩展&#xff1a; 其实我们不想看地址&#xff0c;地址看来没用&#xff0c;我们是用来看对象有没有问题 重写toString: 比如这个如果返回的是地址值&#xff0c;…

【每日渲美学】3ds Max橱柜材质教程:厨房高光烤漆、木纹、亚克力、亚光板材渲染优化指南

在室内可视化项目中&#xff0c;厨房往往是一个集中展现材质表现力与光影质感的关键区域。橱柜作为厨房空间的视觉主体&#xff0c;其材质选择与渲染设置不仅影响整体空间的风格呈现&#xff0c;也对渲染效率提出更高要求。 本期「每日渲美学」&#xff0c;我们聚焦3ds Max环境…

Python Day34

Task&#xff1a; GPU训练及类的call方法 1.CPU性能的查看&#xff1a;看架构代际、核心数、线程数 2.GPU性能的查看&#xff1a;看显存、看级别、看架构代际 3.GPU训练的方法&#xff1a;数据和模型移动到GPU device上 4.类的call方法&#xff1a;为什么定义前向传播时可以直接…

HTTP协议版本的发展(HTTP/0.9、1.0、1.1、2、3)

目录 HTTP协议层次图 HTTP/0.9 例子 HTTP/1.0 Content-Type 字段 Content-Encoding 字段 例子 1.0版本存在的问题&#xff1a;短链接、队头阻塞 HTTP/1.1 Host字段 Content-Length 字段 分块传输编码 1.1版本存在的问题 HTTP/2 HTTP/2数据传输 2版本存在的问题…

开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型

文章目录 开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型主流开源 OIDC(OpenID Connect)身份提供方(IdP)zitadeldexory开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型 主流开源 OIDC(OpenID Connect)身份提供方(IdP) 当前主流的**开源 OIDC(OpenI…

第三十二天打卡

作业&#xff1a;参考pdpbox官方文档中的其他类&#xff0c;绘制相应的图&#xff0c;任选即可 1. 安装并导入库 确保安装与文档版本一致的 pdpbox&#xff08;此处以 0.3.0 为例&#xff09;&#xff1a; bash 复制 下载 pip install pdpbox0.3.0 导入所需库&#xff1a…

【Spring】Spring AI 核心知识(一)

1. 自定义 Advisor 实际上&#xff0c;Advisor 可以看做是 Servlet 当中的“拦截器”&#xff0c;在大模型接收到 prompt 之前进行前置拦截增强&#xff08;比如敏感词校验、记录日志、鉴权&#xff09;&#xff0c;并在大模型返回响应之后进行后置拦截增强&#xff08;比如记…

中国免税品人工智能商城:引领免税品市场新潮流

在全球经济一体化的时代背景下&#xff0c;免税品市场日益繁荣。中国免税品人工智能商城以对标洋码头为目标&#xff0c;积极利用人工智能的优势&#xff0c;结合自身特点&#xff0c;全力打造成为免税品类的示范性商业平台&#xff0c;为消费者带来全新的购物体验。 一、免税品…

LambdaQueryWrapper、MybatisPlus提供的基本接口方法、增删改查常用的接口方法、自定义 SQL

DAY26.2 Java核心基础 MybatisPlus提供的基本接口方法 分页查询 导入依赖springboot整合Mybatis-plus <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version&g…

谢飞机的Java面试奇遇:AIO、BIO、NIO与Netty深度解析

谢飞机的Java面试奇遇&#xff1a;AIO、BIO、NIO与Netty深度解析 在一场充满笑料的面试中&#xff0c;谢飞机面对严肃的面试官&#xff0c;从Java IO的基本概念开始&#xff0c;逐步展开对AIO、BIO、NIO的理解&#xff0c;以及Netty的高级用法。 面试现场&#xff1a;第一轮&…

三、Docker目录挂载、卷映射、网络

目录挂载 如果主机目录为空&#xff0c;则容器内也为空 -v表示目录挂载 冒号前面的是主机上的目录&#xff0c;冒号后面的是docker容器里面的地址 修改主机上的文件&#xff0c;发现docker容器里面的内容也随之改变。 同样修改docker容器里面的内容&#xff0c;主机上的文件…

Linux的学习_基础4_指令的实践

目录&#xff1a; 一、常用功能 二、指令实践 1、tail命令 2、ls命令 3、ps、kill命令 4、cd、vim命令 5、root权限与用户权限的转换 6、获取网卡信息 7、sudo chmodx 8、更换到别的目录 9、获取文件的内容 10、lsblk 查看块设备和文件系统信息 11、man指令与指令…

深入解析Spring Boot与Redis集成:高效缓存与性能优化

深入解析Spring Boot与Redis集成&#xff1a;高效缓存与性能优化 引言 在现代Web应用中&#xff0c;缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的内存数据库&#xff0c;广泛应用于缓存、会话管理和消息队列等场景。本文将详细介绍如何在Spring Boot项目中集…

基于微信小程序的漫展系统的设计与实现

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

蓝桥杯电子赛_零基础利用按键实现不同数字的显现

目录 一、前提 按键的原理图 二、代码配置 bsp_key.c文件 疑问 main.c文件 main.c文件的详细讲解 功能实现 注意事项 一、前提 按键这一板块主要是以记忆为主&#xff0c;我直接给大家讲解代码去实现我要配置的功能。本次我要做的项目是板子上的按键有S4~S19&#xff…

Python常用高阶函数全面解析:通俗易懂的指南

Python常用高阶函数全面解析&#xff1a;通俗易懂的指南 一、什么是高阶函数&#xff1f; 高阶函数(Higher-order Function)是指能够接受其他函数作为参数&#xff0c;或者将函数作为返回值的函数。在Python中&#xff0c;函数是一等公民&#xff0c;可以像普通变量一样传递和…

Flume之选择器:复制和多路复用(比喻化理解

Flume 的选择器决定了Source 如何将数据分发到多个 Channel。这就像 “快递员如何分配包裹到不同的运输通道”&#xff0c;有两种策略&#xff1a;复制和多路复用。 一、复制&#xff08;Replicating Selector&#xff09;&#xff1a;每个 Channel 都送一份 核心逻辑 将同一…

yolov5 安卓运行

参考博客&#xff1a; 通过Android Studio 将yolov5部署到手机端(新手最新适用版)_怎么将yolo部署手机-CSDN博客 总体跟随参考博客走是没问题&#xff0c;有些细节需要注意&#xff1a; 1 jdk 版本选择&#xff0c;jdk需要17&#xff0c;新版的Android Studio 选择jdk版本方式…

day021-定时任务

文章目录 1. cron1.1 检查是否安装1.2 检查是否开机自启动1.3 配置文件与相关命令1.4 配置文件格式 2. 案例2.1 同步时间2.2 定时备份/etc和/var/log目录2.3 定时巡检脚本 3. 练习三剑客过滤3.1 去重统计ip数量3.2 去重统计第7列 用户访问的url的数量3.3 去重统计第9列 状态码与…