QT笔记——信号转发器之QSignalMapper

这篇具有很好参考价值的文章主要介绍了QT笔记——信号转发器之QSignalMapper。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QSignalMapper类可以看成是信号的翻译和转发器。
它可以把一个无参的信号翻译成带以下4种参数的信号再转发:int、QString、 QObject
以及QWidget

应用场景一般是:有一些信号,发送的参数都是一样的情况下,常用的方法是给每一个信号都连接一个槽函数。但这样做,会让代码多一些不必要的复杂,这种情况下,你就可以使用QSignalMapper
qsignalmapper,qt,笔记,ui

下面是 3 个按钮连接 到 对应的 映射数据
setMapping 设置 发射对象 接受的数据

意思:m_signalMapper 作为一个中转站 点击按钮 给到 m_signalMapper,用map来翻译 这个 数据,然后m_signalMapper 发射mapped信号 将刚才翻译的数据发送给 this,这个this 就是我们最终的 接受者
目的:这时候我们就将3个按钮的点击信号 都交给 m_signalMapper 去处理,它发射一个信号mapped 就 节省了 3个按钮 都需要写connect 非必要操作,因为他们的 目的 都是 去 触发showName 这个槽函数,现在我们只需要一个 conenct 就可以解决

	m_signalMapper = new QSignalMapper(this);

	m_signalMapper->setMapping(ui.btn1, "Button 1 clicked");
	m_signalMapper->setMapping(ui.btn2, "Button 2 clicked");
	m_signalMapper->setMapping(ui.btn3, "Button 3 clicked");

	connect(ui.btn1, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn2, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn3, SIGNAL(clicked()), m_signalMapper, SLOT(map()));

	connect(m_signalMapper, SIGNAL(mapped(const QString&)), this, SLOT(showName(const QString&)));
	connect(m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(showStrName(QString)));

结果:

qsignalmapper,qt,笔记,ui
来看一下如果参数为 QObejct是怎么回事

这里有一个StudentInfo 类型 是继承于QObject的,然后分别设置了它的参数,此时我们就知道,点击按钮,然后将 这个学生的信息 交给我们的 m_signalMapper,然后它 在转发给我们的 showStudentInfo 函数,这里函数展示了我们学生的信息情况,也同样不需要写 3个 connect 来操作

	m_s1.SetName("lion");
	m_s1.SetAge(20);

	StudentInfo* s2 = new StudentInfo("cxq", 18);
	StudentInfo* s3 = new StudentInfo("lion_cxq", 22);

	m_signalMapper->setMapping(ui.btn1, &m_s1);
	m_signalMapper->setMapping(ui.btn2, s2);
	m_signalMapper->setMapping(ui.btn3, s3);

	connect(ui.btn1, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn2, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn3, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));

	connect(m_signalMapper, QOverload<QObject*>::of(&QSignalMapper::mapped), this, &QSignalMapperTest::showStudentInfo);

关键的一点是:
我们可以在槽函数中 将QObject 转化为我们 自定义的指针

void QSignalMapperTest::showStudentInfo(QObject* object)
{
	StudentInfo* s = qobject_cast<StudentInfo*>(object);
	if (s)
	{
		qDebug() << s->GetAge() << s->GetName();
	}
}

还有一个就是我们遇到同名的 槽函数时,我们必须要同时两边重载,使用一个即可,否则会报错

	//第一个
	connect(m_signalMapper, QOverload<const QString&>::of(&QSignalMapper::mapped), this, QOverload<const QString&>::of(&QSignalMapperTest::showName));
	//第二个
	connect(m_signalMapper, static_cast<void (QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped), this, static_cast<void (QSignalMapperTest::*)(const QString&)>
(&QSignalMapperTest::showName));

结果:
qsignalmapper,qt,笔记,ui
完整代码:
ui图
qsignalmapper,qt,笔记,ui

.h

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QSignalMapperTest.h"
#include <QSignalMapper>
#include <QDebug>
#include <QVariant>

#define QT5

typedef struct Student
{
	QString name;
	int age;
}Student;
Q_DECLARE_METATYPE(Student)

class StudentInfo :public QObject
{
	Q_OBJECT
public:
	StudentInfo(QObject* parent = nullptr);
	StudentInfo(QString name, int age, QObject* parent = nullptr);

	void SetName(const QString&);
	QString GetName() const;

	void SetAge(const int&);
	int GetAge() const;

private:
	QString m_name;
	int m_age;
};

class QSignalMapperTest : public QWidget
{
    Q_OBJECT

public:
    QSignalMapperTest(QWidget *parent = Q_NULLPTR);

public Q_SLOTS:
	void showName(const QString&);
	void showName(QString, int);
	void showStrName(QString);
	void showStudentInfo(QObject* object);


private:
    Ui::QSignalMapperTestClass ui;

	StudentInfo m_s1;
	QSignalMapper* m_signalMapper;
};

.cpp

#include "QSignalMapperTest.h"

QSignalMapperTest::QSignalMapperTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	m_signalMapper = new QSignalMapper(this);

#if 1
	#ifdef QT5
	m_s1.SetName("lion");
	m_s1.SetAge(20);

	StudentInfo* s2 = new StudentInfo("cxq", 18);
	StudentInfo* s3 = new StudentInfo("lion_cxq", 22);

	m_signalMapper->setMapping(ui.btn1, &m_s1);
	m_signalMapper->setMapping(ui.btn2, s2);
	m_signalMapper->setMapping(ui.btn3, s3);

	connect(ui.btn1, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn2, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn3, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));

	connect(m_signalMapper, QOverload<QObject*>::of(&QSignalMapper::mapped), this, &QSignalMapperTest::showStudentInfo);
	#else
	StudentInfo* s = new StudentInfo("cxq", 18);

	m_signalMapper->setMapping(ui.btn1, s);
	m_signalMapper->setMapping(ui.btn2, s);
	m_signalMapper->setMapping(ui.btn3, s);

	connect(ui.btn1, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn2, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn3, SIGNAL(clicked()), m_signalMapper, SLOT(map()));

	connect(m_signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(showStudentInfo(QObject*)));
	#endif
#endif

#if 0
	#ifdef QT5
	m_signalMapper->setMapping(ui.btn1, "Button 1 clicked");
	m_signalMapper->setMapping(ui.btn2, "Button 2 clicked");
	m_signalMapper->setMapping(ui.btn3, "Button 3 clicked");

	connect(ui.btn1, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn2, &QPushButton::clicked, m_signalMapper, QOverload<>::of(&QSignalMapper::map));
	connect(ui.btn3, &QPushButton::clicked, m_signalMapper, static_cast<void(QSignalMapper::*)()>(&QSignalMapper::map));

	//使用这个报错  必须使用下面第一种或者第二种  因为 槽函数也是重载的
	//connect(m_signalMapper, QOverload<const QString&>::of(&QSignalMapper::mapped), this, &QSignalMapperTest::showName);
	//第一个
	//connect(m_signalMapper, QOverload<const QString&>::of(&QSignalMapper::mapped), this, QOverload<const QString&>::of(&QSignalMapperTest::showName));
	//第二个
	connect(m_signalMapper, static_cast<void (QSignalMapper::*)(const QString&)>(&QSignalMapper::mapped), this, static_cast<void (QSignalMapperTest::*)(const QString&)>(&QSignalMapperTest::showName));
	#else
	m_signalMapper->setMapping(ui.btn1, "Button 1 clicked");
	m_signalMapper->setMapping(ui.btn2, "Button 2 clicked");
	m_signalMapper->setMapping(ui.btn3, "Button 3 clicked");

	connect(ui.btn1, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn2, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
	connect(ui.btn3, SIGNAL(clicked()), m_signalMapper, SLOT(map()));

	//可以
	connect(m_signalMapper, SIGNAL(mapped(const QString&)), this, SLOT(showName(const QString&)));
	connect(m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(showStrName(QString)));
	//不可以  多个参数不可以
	//connect(m_signalMapper, SIGNAL(mapped(QString,int)), this, SLOT(showName(QString,int)));
	#endif
#endif
}

void QSignalMapperTest::showName(const QString& str)
{
	qDebug() << str;
}

void QSignalMapperTest::showName(QString name, int age)
{
	qDebug() << QStringLiteral("姓名:");
}

void QSignalMapperTest::showStrName(QString str)
{
	qDebug() << str;
}

void QSignalMapperTest::showStudentInfo(QObject* object)
{
	StudentInfo* s = qobject_cast<StudentInfo*>(object);
	if (s)
	{
		qDebug() << s->GetAge() << s->GetName();
	}
}

StudentInfo::StudentInfo(QObject* parent)
{

}

StudentInfo::StudentInfo(QString name, int age, QObject* parent )
{
	m_name = name;
	m_age = age;
}

void StudentInfo::SetName(const QString& name )
{
	m_name = name;
}

QString StudentInfo::GetName() const
{
	return m_name;
}

void StudentInfo::SetAge(const int& age)
{
	m_age = age;
}

int StudentInfo::GetAge() const
{
	return m_age;
}

参考博客:
QSignalMapper介绍
QSignalMapper使用文章来源地址https://www.toymoban.com/news/detail-705336.html

到了这里,关于QT笔记——信号转发器之QSignalMapper的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL笔记-第17章_触发器

    视频链接:【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信息 分别存放在 2 个不同

    2024年02月05日
    浏览(30)
  • Qt信号和信号槽(二)

    目录 信号槽使用拓展 示例1(一个信号可以对应多个槽函数)(在上篇文章的代码中进行修改):  示例2(用信号连接信号):  信号槽的连接方式 示例: Lambda表达式 语法格式 定义和调用 一个信号可以连接多个槽函数, 发送一个信号有多个处理动作         需要写多个conn

    2024年02月11日
    浏览(24)
  • verilog学习笔记6——锁存器和触发器

    2023.8.15 信号高电平有效 R :复位端 S :置位端 表达式: Q = S + R\\\' Qn 约束条件:SR=0,也就是SR不能同时为1 信号低电平有效 R :复位端 S :置位端 表达式: Q = S\\\' + R Qn 约束条件:S+R=1,也就是SR不能同时为0 E = 0 :锁存器保持不变,锁住 E = 1 :相当于正常得SR锁存器 把S取反接到

    2024年02月12日
    浏览(32)
  • 1.1.4 Qt信号槽之再谈Qt4与Qt5中信号槽使用的差异

    Differences between String-Based and Functor-Based Connections 通过上面的示例和分析,我们已经明显感受到Qt4和Qt5中connect的不同之处,但是Qt文档中有一篇文章专门叙述了Qt4和Qt5中connect的差异,这里根据此篇文章带着大家再深入了解拓展一下。 从Qt5开始,Qt提供了两种不同方法的信号槽连

    2024年02月11日
    浏览(28)
  • 嵌入式QT (Qt 信号与槽)

    因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。 信号 (Signal)就是在特定情况下被发射的事件。 GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就

    2024年02月02日
    浏览(40)
  • Qt6.2教程——3.Qt信号和槽

    信号和槽是Qt中一个强大的特性,用于处理对象之间的通信。它们是一种事件处理机制,允许一个对象在某个事件发生时通知另一个对象。 定义 : 信号是一个QObject的成员函数,当某个特定事件发生时,它被自动调用。它可以与一个或多个槽关联。 声明 : 在Qt类的声明中,信号

    2024年02月10日
    浏览(29)
  • 嵌入式Qt Qt中的信号处理

    Qt消息模型: - Qt封装了具体操作系统的消息机制 - Qt遵循经典的GUI消息驱动事件模型 Qt中定义了与系统消息相关的概念;   Qt中的消息处理机制: Qt的核心 QObject::cinnect函数: Qt中的“新”: 实验1 初探信号与槽   运行结果: - 只有QObject的子类才能自定义槽 - 定义槽的

    2024年02月22日
    浏览(37)
  • WPF 零基础入门笔记(1):WPF静态页面,布局+样式+触发器

    WPF 零基础入门笔记(0):WPF简介 WPF MaterialDesign 初学项目实战(0):github 项目Demo运行 WPF MaterialDesign 初学项目实战(1)首页搭建 WPF MaterialDesign 初学项目实战(2)首页导航栏样式 WPF MaterialDesign 初学项目实战(3)动态侧边栏 WPF MaterialDesign 初学项目实战(4)侧边栏路由管理

    2024年02月11日
    浏览(26)
  • QT之信号和槽

    一、什么是信号和槽? 我们经常看到的功能,点击一个按钮实现窗口关闭。 这一过程发生了什么?是怎么实现的 按钮相当于一个信号,点击相当于发送一个信号,窗口是个接收者,关闭窗口是个槽函数 信号:各种事件 槽:响应信号的动作 当一个按钮(信号)被触发(发送

    2024年02月07日
    浏览(24)
  • 【QT】信号和槽(15)

    前面的内容说了很多不同的控件如何使用,今天来看下QT的核心, 信号与槽(Signals and slots) ! 简单理解一下,就是我们的信号与槽连接上了之后,发射一个信号给到槽,槽函数接收到了这个信号之后,槽函数会被调用。 1.python 3.7.8   可直接进入官网下载安装:Download Pyt

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包