QSignalMapper信号映射器的使用

简介: QSignalMapper信号映射器的使用

QSignalMapper介绍

该类收集一组无参数的信号,并使用与发送信号的对象对应的整数、字符串或对象参数重新发出它们。在大多数情况下,可以使用lambdas将自定义参数传递给槽。这样成本更低,并且可以简化代码。


该类支持使用setMapping()将特定字符串、整数、对象和小部件映射到特定对象。

然后,对象的信号可以连接到map()插槽,该插槽将发出一个与原始信号对象相关的值的信号(可以是mappedInt(), mappedString()和mappedObject())。最后可以使用removemaps()删除映射。


Signal 信号

该类主要有以下三个信号可以进行绑定,这取决于你使用setMapping()时传入的标识类型。

 void mappedInt(int i)
 void mappedObject(QObject *object)
 void mappedString(const QString &text)

slots

对象的信号可以关联到map()中,根据自己需求选择合适的重载版本。

void map(QObject *sender)
 void map()


根据标识获取对象

通过mapping可以根据特定的标识获取原本的对象。

 QObject *mapping(int id) const
 QObject *mapping(const QString &id) const
 QObject *mapping(QObject *object) const


给对象设置标识

通过setMapping方法可以给对象设置标识。

 void setMapping(QObject *sender, int id)
 void setMapping(QObject *sender, const QString &text)
 void setMapping(QObject *sender, QObject *object)

删除映射

不需要映射时,通过removeMappings方法传入对应的对象即可删除映射。

void removeMappings(QObject *sender)


实例

现假设有多个按钮(QPushButton),需要根据不同的按钮点击输出不同的词语,那么我们就可以完美的使用QSignalMapper来处理。

代码

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    signalMapper.setMapping(ui->pushButton, "type1");
    connect(ui->pushButton, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_2, "type2");
    connect(ui->pushButton_2, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_3, "type3");
    connect(ui->pushButton_3, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_4, "type4");
    connect(ui->pushButton_4, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_5, "type5");
    connect(ui->pushButton_5, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    connect(&signalMapper, &QSignalMapper::mappedString, this, &MainWindow::ShowName);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::ShowName(QString str)
{
    // 相同的逻辑抽出来
    qDebug() << "ShowName:";
    if(str == "type1")
    {
        qDebug() << u8"天菜";
    }
    else if(str == "type2")
    {
        qDebug() << u8"傻子";
    }
    else if(str == "type3")
    {
        qDebug() << u8"秀才";
    }
    else if(str == "type4")
    {
        qDebug() << u8"天才";
    }
    else if(str == "type5")
    {
        qDebug() << u8"77";
    }
}


需求升级

现在点击哪个按钮,需要将哪个按钮禁用掉。那么通过QSignalMapeer更加简单。

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    signalMapper.setMapping(ui->pushButton, ui->pushButton);
    connect(ui->pushButton, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_2, ui->pushButton_2);
    connect(ui->pushButton_2, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_3, ui->pushButton_3);
    connect(ui->pushButton_3, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_4, ui->pushButton_4);
    connect(ui->pushButton_4, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
    signalMapper.setMapping(ui->pushButton_5, ui->pushButton_5);
    connect(ui->pushButton_5, &QPushButton::clicked, &signalMapper, QOverload<>::of(&QSignalMapper::map));
   connect(&signalMapper, &QSignalMapper::mappedObject, this, &MainWindow::ShowObject);
}
void MainWindow::ShowObject(QObject *btn)
{
    ((QPushButton*)(btn))->setEnabled(false);
}


总结

上述的实例场景可能都有点勉强,但是实际工作中,使用的场景很多,例如功能区的按钮,弹窗类的按钮需要根据自身的大小放到对应的位置,正常情况下·,你可能就会写很多个槽进行实现,虽然可能不完全一样,但是逻辑都是相同的,代码看着也冗余。

目录
相关文章
|
安全 数据处理 C++
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
3028 3
|
算法 C语言 C++
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)(一)
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)
4165 1
|
存储 SQL 人工智能
CCCF专栏 | 加密数据库技术:前沿与展望
本文将从数据安全防护的重大战略需求出发,聚焦数据安全搜索、加密数据库技术等前沿领域,深入探讨加密数据库的发展现状,揭示其设计过程中存在的安全性和性能方面的挑战,并提出未来关于加密数据库建设的一些愿景。
CCCF专栏 | 加密数据库技术:前沿与展望
|
8月前
|
Shell Linux Ruby
Python3虚拟环境venv
`venv` 是 Python 的虚拟环境工具,用于为不同项目创建独立的运行环境,避免依赖冲突。通过 `python3 -m venv` 命令创建虚拟环境,并使用 `source bin/activate` 激活。激活后,所有 Python 包将安装在该环境中,不影响系统全局环境。退出环境使用 `deactivate` 命令。每个虚拟环境拥有独立的包集合,确保项目间的隔离性。删除虚拟环境只需删除其目录即可。
490 34
|
C++ 索引
【Qt 学习笔记】如何在Qt中打印日志 | qDebug的使用 | Assistant的使用
【Qt 学习笔记】如何在Qt中打印日志 | qDebug的使用 | Assistant的使用
1693 0
|
9月前
|
安全 编译器 C语言
【C语言】typeof 关键字详解
`typeof` 关键字在GCC中用于获取表达式的类型,便于动态类型定义和宏编程。它可以用于简化代码、提高代码的灵活性和可维护性。虽然 `typeof` 是 GCC 扩展,并非标准C的一部分,但它在实际编程中非常有用。
371 1
|
人工智能 资源调度 算法
算法金 | 一个强大的算法模型,GPR !!
高斯过程回归(GPR)是基于高斯过程的非参数贝叶斯方法,用于捕捉数据的非线性关系并提供不确定性估计。它利用核函数描述输入数据的潜在函数,如径向基函数(RBF)用于平滑建模。GPR通过最大化对数似然函数选择超参数。代码示例展示了如何使用`sklearn`库进行GPR,生成模拟数据,训练模型,并用RBF核函数进行预测,最后通过绘图展示预测结果及置信区间。
423 3
算法金 | 一个强大的算法模型,GPR !!
|
传感器 数据采集 监控
QModbus例程分析
QModbus例程分析
|
网络协议
netstat 查看端口开放情况
netstat 查看端口开放情况
657 0
|
应用服务中间件 Nacos nginx
nacos 2.3.2模式 standalone 使用nginx 反向代理之后访问nacos控制台静
nacos 2.3.2模式 standalone 使用nginx 反向代理之后访问nacos控制台静