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

分享一个Qt使用的模块间通信类

需求:

不同线程,或者同一线程的不同类之间通信,按照Qt的机制,定义一个信号,一个槽,然后绑定。以两个类A,B为例,A触发一个信号,B执行一个槽,在定义好信号和槽之后,需要在另一处,将两个类的信号和槽进行绑定。如果模块特别多,绑了绑去 略显麻烦,耦合性太高。

此处分享一个类,别人写的,忘记了在哪看到的。可以将上述问题解决,降低耦合性。

使用:

1,A B两个类都需要包含头文件。#include "PSEventController.h"

2, A类中触发的地方,调用publish函数。

//比如按下按钮 ,需提供一个唯一的标识字符串,可自定义参数 
PSEventController::publish(actionName.toLatin1(),Q_ARG(bool,isChecked));

3,B类中 定义 on_psEvent_xxx 函数,并实现。

//此处的addLine 即为上述pulish 函数中的第一个参数,isChecked 为publis中的第二个参数
void on_psEvent_addLine(bool isChecked);

4,B类中初始化的时候 执行 subscribe 函数。

PSEventController::subscribe(this,"addLine");

这样,A 和B 两个类 发布和订阅的唯一字符串标识符只要一致,A 在pubsh 的时候 B 就可以subscribe到,并且A 和B 完全耦合,相互不可见。

具体代码:

//PSEventController.h
#ifndef PSEVENTCONTROLLER_H
#define PSEVENTCONTROLLER_H#include <QObject>
#include <QReadWriteLock>
#include <QMap>
#include <QList>#define METHOD_PREFIX "on_psEvent_"class PSEventController : public QObject
{Q_OBJECT
public:static void unSubscribe(QObject* listener, const QByteArray& eventName);static bool subscribe(QObject* listener, const QByteArray& eventName);static bool publish(const QByteArray& eventName, Qt::ConnectionType connectionType,QGenericArgument val0 = QGenericArgument(), QGenericArgument val1 = QGenericArgument(),QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(),QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(),QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(),QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument());static inline bool publish(const QByteArray& eventName,QGenericArgument val0 = QGenericArgument(), QGenericArgument val1 = QGenericArgument(),QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(),QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(),QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(),QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()){return publish(eventName, Qt::AutoConnection, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);}static inline QString get_Errors(){return ps_LastError_;}static inline void clearEvents(){QWriteLocker locker(&ps_Lock_);psEvents_pool_.clear();}static inline QByteArray methodFormatting(const QByteArray& eventName) {return METHOD_PREFIX + eventName;}
private:static QMap<QByteArray, QList<QObject*>> psEvents_pool_;static QReadWriteLock ps_Lock_;static QString ps_LastError_;
};#endif // PSEVENTCONTROLLER_H
//PSEventController.cpp
#include "PSEventController.h"
#include <QWriteLocker>QMap<QByteArray, QList<QObject*>> PSEventController::psEvents_pool_;
QReadWriteLock PSEventController::ps_Lock_;
QString PSEventController::ps_LastError_;void PSEventController::unSubscribe(QObject* listener, const QByteArray& eventName)
{QWriteLocker locker(&ps_Lock_);int index = -1;if (psEvents_pool_.contains(eventName) &&(index = psEvents_pool_[eventName].indexOf(listener)) >= 0 && index < psEvents_pool_[eventName].count())psEvents_pool_[eventName].takeAt(index);
}bool PSEventController::subscribe(QObject* listener, const QByteArray& eventName)
{QWriteLocker locker(&ps_Lock_);if (psEvents_pool_.contains(eventName)) {if (-1 != psEvents_pool_[eventName].indexOf(listener)) {ps_LastError_ = QString("This object is subscribed to this eventName");return false;}psEvents_pool_[eventName].push_back(listener);return true;} else {psEvents_pool_.insert(eventName, { listener });return true;}
}bool PSEventController::publish(const QByteArray& eventName, Qt::ConnectionType connectionType,QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3,QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7,QGenericArgument val8, QGenericArgument val9)
{QReadLocker locker(&ps_Lock_);if (!psEvents_pool_.contains(eventName)) {ps_LastError_ = QString("No objects subscribe to this eventName");return false;}auto methodName = methodFormatting(eventName);QStringList errors;for (auto listener : psEvents_pool_[eventName]) {if (!listener)continue;auto ret = QMetaObject::invokeMethod(listener, methodName, connectionType,val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);if (!ret)errors.append(QString("%1:%2").arg(listener->metaObject()->className()).arg(listener->objectName()));}if (errors.isEmpty())return true;ps_LastError_ = QString("%1 execution failed:[\n").arg(QString(eventName));for (auto& err : errors)ps_LastError_ += QString("%1;\n").arg(err);ps_LastError_ += "]\n";return false;
}

相关文章:

分享一个Qt使用的模块间通信类

需求&#xff1a; 不同线程&#xff0c;或者同一线程的不同类之间通信&#xff0c;按照Qt的机制&#xff0c;定义一个信号&#xff0c;一个槽&#xff0c;然后绑定。以两个类A,B为例&#xff0c;A触发一个信号&#xff0c;B执行一个槽&#xff0c;在定义好信号和槽之后&#x…...

工作七年,对消息推送使用的一些经验和总结

前言&#xff1a;不管是APP还是WEB端都离不开消息推送&#xff0c;尤其是APP端&#xff0c;push消息&#xff0c;小信箱消息&#xff1b;WEB端的代办消息等。因在项目中多次使用消息推送且也是很多项目必不可少的组成部分&#xff0c;故此总结下供自己参考。 一、什么是消息推…...

计网——应用层

应用层 应用层协议原理 网络应用的体系结构 客户-服务器&#xff08;C/S&#xff09;体系结构 对等体&#xff08;P2P&#xff09;体系结构 C/S和P2P体系结构的混合体 客户-服务器&#xff08;C/S&#xff09;体系结构 服务器 服务器是一台一直运行的主机&#xff0c;需…...

算法面试八股文『 基础知识篇 』

博客介绍 近期在准备算法面试&#xff0c;网上信息杂乱不规整&#xff0c;出于强迫症就自己整理了算法面试常出现的考题。独乐乐不如众乐乐&#xff0c;与其奖励自己&#xff0c;不如大家一起嗨。以下整理的内容可能有不足之处&#xff0c;欢迎大佬一起讨论。 PS&#xff1a;…...

docker-学习-4

docker学习第四天 docker学习第四天1. 回顾1.1. 容器的网络类型1.2. 容器的本质1.3. 数据的持久化1.4. 看有哪些卷1.5. 看卷的详细信息 2. 如何做多台宿主机里的多个容器之间的数据共享2.1. 概念2.2. 搭NFS服务器实现多个容器之间的数据共享的详细步骤2.3. 如果是多台机器&…...

el-upload子组件上传多张图片(上传为files或base64url)

场景&#xff1a; 在表单页&#xff0c;有图片需要上传&#xff0c;表单的操作行按钮中有上传按钮&#xff0c;点击上传按钮。 弹出el-dialog进行图片的上传&#xff0c;可以上传多张图片。 由于多个表单页都有上传多张图片的操作&#xff0c;因此将上传多图的el-upload定义…...

2024美赛数学建模C题思路源码——网球选手的动量

这题挺有意思,没具体看比赛情况,打过比赛的人应该都知道险胜局(第二局、第五局逆转局)最影响心态的,导致第3、5局输了 模型结果需要证明这样的现象 赛题目的 赛题目的:分析网球球员的表现 问题一.球员在比赛特定时间表现力 问题分析 excel数据:每个时间段有16场比赛,…...

金三银四_程序员怎么写简历_写简历网站

你们在制作简历时,是不是基本只关注两件事:简历模板,还有基本信息的填写。 当你再次坐下来更新你的简历时,可能会发现自己不自觉地选择了那个“看起来最好看的模板”,填写基本信息,却没有深入思考如何使简历更具吸引力。这其实是一个普遍现象:许多求职者仍停留在传统简历…...

echarts条形图添加滚动条

效果展示: 测试数据: taskList:[{majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {maj…...

Java 使用Soap方式调用WebService接口

pom文件依赖 <dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.0</version></dependency><!-- https://mvnrepository.com/artif…...

2024美赛数学建模所有题目思路分析

美赛思路已更新&#xff0c;关注后可以获取更多思路。并且领取资料 C题思路 首先&#xff0c;我们要理解势头是什么。简单来说&#xff0c;势头是一方在比赛中因一系列事件而获得的动力或优势。在网球中&#xff0c;这可能意味着连续赢得几个球&#xff0c;或是在比赛的某个关…...

Docker容器引擎(5)

目录 一.docker-compose docker-compose的三大概念&#xff1a; yaml文件格式&#xff1a; json文件格式&#xff1a; docker-compose 配置模板文件常用的字段&#xff1a; 二.Docker Compose 环境安装&#xff1a; 查看版本&#xff1a; 准备好nginx 的dockerfile的文…...

百分点科技:《数据科学技术: 文本分析和知识图谱》

科技进步带来的便利已经渗透到工作生活的方方面面&#xff0c;ChatGPT的出现更是掀起了新一波的智能化浪潮&#xff0c;推动更多智能应用的涌现。这背后离不开一个朴素的逻辑&#xff0c;即对数据的收集、治理、建模、分析和应用&#xff0c;这便是数据科学所重点研究的对象——…...

LabVIEW传感器通用实验平台

LabVIEW传感器通用实验平台 介绍了基于LabVIEW的传感器实验平台的开发。该平台利用LabVIEW图形化编程语言和多参量数据采集卡&#xff0c;提供了一个交互性好、可扩充性强、使用灵活方便的传感器技术实验环境。 系统由硬件和软件两部分组成。硬件部分主要包括多通道数据采集卡…...

向日葵企业“云策略”升级 支持Android 被控策略设置

此前&#xff0c;贝锐向日葵推出了适配PC企业客户端的云策略功能&#xff0c;这一功能支持管理平台统一修改设备设置&#xff0c;上万设备实时下发实时生效&#xff0c;很好的解决了当远程控制方案部署后&#xff0c;想要灵活调整配置需要逐台手工操作的痛点&#xff0c;大幅提…...

51单片机通过级联74HC595实现倒计时秒表Protues仿真设计

一、设计背景 近年来随着科技的飞速发展&#xff0c;单片机的应用正在不断的走向深入。本文阐述了51单片机通过级联74HC595实现倒计时秒表设计&#xff0c;倒计时精度达0.05s&#xff0c;解决了传统的由于倒计时精度不够造成的误差和不公平性&#xff0c;是各种体育竞赛的必备设…...

深信服技术认证“SCCA-C”划重点:深信服云计算关键技术

为帮助大家更加系统化地学习云计算知识&#xff0c;高效通过云计算工程师认证&#xff0c;深信服特推出“SCCA-C认证备考秘笈”&#xff0c;共十期内容。“考试重点”内容框架&#xff0c;帮助大家快速get重点知识。 划重点来啦 *点击图片放大展示 深信服云计算认证&#xff08…...

Redis stream特性了解

在发布订阅中我们了解到发布订阅模式存在的无法持久化保存消息和对于离线重连的客户端不能读取历史消息的缺陷&#xff0c;以下就来了解一下stream是如何解决这个问题的 steam是类似于仅添加log的数据结构&#xff0c;提供了以下基本命令 XADD: 添加新条目到stream # 语法xadd…...

苍穹外卖项目可以写的简历和如何优化简历

文章目录 重点写中规写添加自己个性的项目面试会问道的问题 我是一名双非大二计算机本科生&#xff0c;希望我的分享对你有帮助&#xff0c;点赞关注不迷路。 简历编写一直是很多人求职人的心病&#xff0c;我自己上学期有一门课程是去校内企业面试&#xff0c;当时我就感受出…...

C++:智能指针

C在用引用取缔掉指针的同时&#xff0c;模板的引入带给了指针新的发挥空间 智能指针简单的来说就是带有不同特性和内存管理的指针模板 unique_ptr 1.不能有多个对象指向一块内存 2.对象释放时内部指针指向地址也随之释放 3.对象内数据只能通过接口更改绑定 4.对象只能接收右值…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...