(9)Qt中信号与槽重载的解决方案

news2024/11/25 2:22:24

信号与槽重载的解决方案

一、通过函数指针解决

//信号
void (Me::*funchungury)() = &Me::hungury;
void (Me::*funchungury_QString)(QString) = &Me::hungury;
//槽
void (Me::*funceat)() = &Me::eat;
void (Me::*funceat_QString)(QString) = &Me::eat;

//有参连接
connect(me,funchungury_QString,me,funceat_QString);
//无参连接
connect(me,funchungury,me,funceat);

继续使用自定义信号时使用的父子窗口切换的案例:

/*
    SubWidget.h文件中添加一个openMainWindow(const QString&)重载信号
*/
#ifndef _SUBWIDGET_H_
#define _SUBWIDGET_H_
#include <QWidget>
#include <QPushButton>

class SubWidget : public QWidget
{
	Q_OBJECT
public:
	SubWidget(QWidget* parent = nullptr);
	~SubWidget();
private:
	QPushButton* m_btn;
signals:
	void openMainWindow();						//	自定义信号
	void openMainWindow(const QString&);		//	带参数的自定义信号
};

#endif
/*
    使用emit发送信号
*/
#include "SubWidget.h"

SubWidget::SubWidget(QWidget* parent)
	:QWidget(parent)
{
	resize(400, 400);
	setWindowTitle("子窗口");

	m_btn = new QPushButton("切换到父窗口", this);
	
	//使用emit发送信号
	connect(m_btn, &QPushButton::clicked, this, [=](){
		emit openMainWindow();
		emit openMainWindow(QString("我是重载的信号"));
	});
}

SubWidget::~SubWidget()
{

}
/*
    Widget.h文件中添加重载的槽函数funcSlot(const QString& msg);
*/
#ifndef _WIDGET_H_
#define _WIDGET_H_

#include <QWidget>
#include <QPushButton>
#include "SubWidget.h"

class SubWidget;
class Widget : public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr);
	~Widget();
public slots:
	void funcSlot();						//	不带参数的槽函数
	void funcSlot(const QString& msg);		//	带参数的槽函数
private:
	QPushButton* m_btn = nullptr;
	SubWidget* m_subWidget = nullptr;
};

#endif
#include"Widget.h"

Widget::Widget(QWidget* parent)
	:QWidget(parent)
{
	resize(640, 480);								// 设置父窗口大小
	setWindowTitle("父窗口");						// 设置父窗口标题

	m_btn = new QPushButton("切换到子窗口", this);
	m_subWidget = new SubWidget;

	//实现从父窗口切换到子窗口的效果
	connect(m_btn, &QPushButton::clicked,[=]() {
		this->hide();
		m_subWidget->show();
	});

	//实现从子窗口切换到父窗口的效果
	//使用函数指针的方式解决信号重载	槽重载
	void (SubWidget:: * signalFunc)() = &SubWidget::openMainWindow;
	void (SubWidget:: * signalFunc2)(const QString&) = &SubWidget::openMainWindow;

	void (Widget:: * slotFunc)() = &Widget::funcSlot;
	void (Widget:: * slotFunc2)(const QString&) = &Widget::funcSlot;

	connect(m_subWidget, signalFunc, this, slotFunc);			//	无参连接
	//connect(m_subWidget, signalFunc2, this, slotFunc2);			//	带参连接
}

Widget::~Widget()
{

}

//槽函数
void Widget::funcSlot()
{
	this->show();
	m_subWidget->hide();
}
//重载的带参数的槽函数
void Widget::funcSlot(const QString& msg)
{
	this->show();
	m_subWidget->hide();
	setWindowTitle(msg);
}

上面的案例中,有参数的连接会改变父窗口的标题,没有参数的连接不会改变父窗口的标题。

不带参数的连接:

 

带参数的连接:

 

二、通过Qt提供的重载类(QOverload)解决

//有参连接
connect(this,QOverload<QString>::of(&MyButton::hungury),
        this,QOverload<QString>::of(&MyButton::eat));
//无参连接
connect(this,QOverload<>::of(&MyButton::hungury),
        this,QOverload<>::of(&MyButton::eat));

直接使用QOverload类的方式解决父子窗口切换信号与槽重载的问题:

//使用QOverload的方式解决信号重载	槽重载
connect(m_subWidget, QOverload<>::of(&SubWidget::openMainWindow), 
	this, QOverload<>::of(&Widget::funcSlot));							//	无参连接
connect(m_subWidget, QOverload<const QString&>::of(&SubWidget::openMainWindow),
	this, QOverload<const QString&>::of(&Widget::funcSlot));			//	带参连接

三、使用Qt4的方式解决

        这种旧的信号与槽的连接方式在Qt6中是支持的, 但是不推荐使用, 因为这种方式在进行信号槽连接的时候, 信号和槽函数通过宏SIGNALSLOT转换为字符串类型。因为信号和槽函数的转换是通过宏来进行转换的,因此传递到宏函数内部的数据不会被进行检测, 如果使用者传错了数据,编译器也不会报错,但实际上信号槽的连接已经不对了,只有在程序运行起来之后才能发现问题,而且问题不容易被定位。

Me m;
// Qt4处理方式  注意不要把信号与槽的名字写错了,因为是转为字符串写错了不会报错,但是连接会失败
connect(&m, SIGNAL(eat()), &m, SLOT(hungury()));
connect(&m, SIGNAL(eat(QString)), &m, SLOT(hungury(QString)));

// Qt5处理方式
connect(&m, &Me::eat, &m, &Me::hungury);	// error:no matching member function for call to 'connect'

直接使用Qt4的方式解决父子窗口切换信号与槽重载的问题:

//使用Qt4的方式解决信号重载	槽重载
connect(m_subWidget, SIGNAL(openMainWindow()),
	this, SLOT(funcSlot()));
connect(m_subWidget, SIGNAL(openMainWindow(const QString&)),
	this, SLOT(funcSlot(const QString&)));

总结 

  • Qt4的信号槽连接方式使用了宏函数, 宏函数对用户传递的信号槽不会做错误检测, 容易出bug

  • Qt5的信号槽连接方式, 传递的是信号槽函数的地址, 编译器会做错误检测, 减少了bug的产生

  • 当信号槽函数被重载之后, Qt4的信号槽连接方式不受影响,Qt6中需要给被重载的信号或者槽定义函数指针或者使用QOverload

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

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

相关文章

Oracle与MySQL语法转换

前言 Oracle与MySQL语法转换 场景&#xff1a;系统改造&#xff0c;需要由Oracle切换为MySQL&#xff0c;因而要对代码中的Oracle语法的sql调整为MySQL语法 博客地址&#xff1a;芒果橙的个人博客 【http://mangocheng.com】 sysdate–当前日期 Oracle 使用sysdate select s…

hdl_graph_slam代码解析

hdl SLAM和定位的关系&#xff1a;HDL和cartographer一样&#xff0c;是离线建图的 整个SLAM系统的架构 包含四个节点&#xff1a; 预处理、 帧匹配、hdl_slam、地面检测 输入点云首先经过预处理进行降采样&#xff0c;然后传给下一个节点。帧匹配通过迭代获取两帧之间运动变化…

【SpringCloud01】微服务架构入门

1.微服务架构理论入门 SpringCloud微服务 2.Boot和Cloud版本选型 上篇&#xff1a;SpringBoot2.X版和SpringCloud H版 下篇&#xff1a;SpringCloud Alibaba 官网强烈推荐SpringBoot2.0以上的版本 Cloud与Boot之间的版本关系 技术选型相关的网站使用在线解析json字符串 由于…

第2章 马尔可夫决策过程

2.1 马尔可夫决策过程&#xff08;上&#xff09; Markov Decision Process&#xff08;MDP&#xff09; Markov Decision Process can model a lot of real-world problem. It formally describes the framework of reinforcement learningUnder MDP, the environment is ful…

Promise 实现 (从简易版到符合Promise A+规范)

前言 手写 Promise 是面试的时候大家都逃避的送命题&#xff0c;在学些了解后发现通过实现源码更能将新一代的异步方案理解的通透&#xff0c;知其然知其所以然的运用。 如果直接将源码贴到此处势必不能有更大的收获&#xff0c;下面就按实现版本来看做简要分析。 回顾 Prom…

SpringBoot测试类编写

前置要求: a.测试类上需要的注解 SpringBootTest AutoConfigureMockMvc Slf4j b.引入MockMvc类 Autowired private MockMvc mockMvc; c.如果需要前置条件可以用before注解 1.get/delete请求 // 查询Testvoid testQuery() throws Exception {String content mockMvc.perfor…

Django(15):身份和权限认证

目录1.Django中的身份认证模块1.1 用户模型1.2 认证模块1.3 项目搭建演示2.权限管理架构2.1 权限相关数据模型2.2 权限相关功能函数2.3 权限分配函数2.4 权限设置3.资源访问管理1.Django中的身份认证模块 1.1 用户模型 Django中有内建的用户模块django.contrib.auth.models.U…

2022 CNCC 中国计算机大会参会总结

前言 第 19 届 CNCC 于2022年12月8-10日召开&#xff0c;本届大会为期三天&#xff0c;首次采取全线上举办形式&#xff0c;主题为“算力、数据、生态”&#xff0c;重点在保持多样性、聚焦热点前沿话题、平衡学术界和产业界参与等维度展开讨论。大会由CCF会士、中国科学院院士…

【SpringBoot】一文带你入门SpringBoot

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Spring】 &#x1f96d;本文内…

【职场进阶】做好项目管理,先从明确职责开始

优秀的项目管理一定是高效协调各方资源、反馈及时、调整迅速的。 同时可以做到让参与各方在整个项目过程中张弛有序、愉快合作&#xff0c;最终实现产品项目的效益最大化。 那什么是项目呢&#xff1f; 项目是为向客户提供独特的产品或服务而进行的临时性任务&#xff0c;项目有…

TypeScript 对象key为number时的坑

首先在js的对象中有一个设定&#xff0c;就是对象的key可以是字符串&#xff0c;也可以是数字。 不论key是字符串还是数字&#xff0c;遍历对象key的时候&#xff0c;这个key会变成字符串 通过[] 操作符访问key对应值时候&#xff0c;不论是数字还是字符串都转成了 字符串的k…

Chromedriver安装教程

第一步 查看你当前Chrome浏览器的版本&#xff0c;如下图所示&#xff1a; 第二步 查看当前Chrome浏览器的版本号&#xff0c;如下图所示,版本 108.0.5359.125&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09;中的&#xff0c;108就是我们的版本号。 第三…

VTK-PointPlacer

前言&#xff1a;本博文主要研究VTK中点转换到曲面上的应用&#xff0c;相关的接口为vtkPolygonalSurfacePointPlacer&#xff0c;为深入研究将基类vtkPointPlacer开始讲解。主要应用为在PolyData表面进行画线。 vtkPointPlacer 描述&#xff1a;将2D display位置转换为世界坐…

ospf知识点汇总

OSPF &#xff1a; 开放式最短路径优先协议使用范围&#xff1a;IGP 协议算法特点&#xff1a; 链路状态型路由协议&#xff0c;SPF算法协议是否传递网络掩码&#xff1a;传递网络掩码协议封装&#xff1a;基于IP协议封装&#xff0c;协议号为 89一.OSPF 特点1.OSPF 是一种典型…

基于javaweb(springboot+mybatis)网上酒类商城项目设计和实现以及文档报告

基于javaweb(springbootmybatis)网上酒类商城项目设计和实现以及文档报告 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏…

【Linux】Linux项目自动化构建工具—make/Makefile

目录一.什么是make/MakefileMakefilemake二.Makefile逻辑1.简单依赖2.复杂依赖三.make指令1.make的使用2.clean清理3.伪目标4.make如何确定是否编译访问时间的影响修改时间的影响一.什么是make/Makefile Makefile 在Windows下&#xff0c;我们使用VS、VS Code这些ide编写C/C程…

MySQL的客户端/服务器架构

以我们平时使用的微信为例&#xff0c;它其实是由两部分组成的&#xff0c;一部分是客户端程序&#xff0c;一部分是服务器程序。客户端可能有很多种形式&#xff0c;比如手机APP&#xff0c;电脑软件或者是网页版微信&#xff0c;每个客户端都有一个唯一的用户名&#xff0c;就…

赶紧收藏 | 50个超实用微信小程序,巨好用|||内含免费配音软件

现在App太多了&#xff0c;想用的功能都要下载&#xff0c;但是手机有258g内存不允许这么放肆呀&#xff0c;只能挖掘不占用存的方法了&#xff0c;小程序就解决了这个痛&#xff0c;节省内存&#xff0c;让手机不再卡顿&#xff0c;打游戏也舒服.给大家整理了50个很好用的小程…

【阶段三】Python机器学习11篇:机器学习项目实战:KNN(K近邻)回归模型

本篇的思维导图: 项目实战(KNN回归模型) K近邻算法回归模型则将离待预测样本点最近的K个训练样本点的平均值进行待预测样本点的回归预测。 项目背景 K近邻除了能进行分类分析,还能进行回归分析,即预测连续变量,此时的KNN称为K近邻回归模型。回归问题是一类…

synchronized 重量级锁分析

synchronized 重量级锁分析 1. 背景 在JDK1.6以前&#xff0c;synchronized 的工作方式都是这种重量级的锁。它的实现原理就是利用 kernel 中的互斥量,mutex。主要是内核中的mutex 能够保证它是一个互斥的量。如果线程1拿到了 mutex,那么线程2就拿不到了。这是内核帮我们保证…