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);
}

总结

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


相关文章

Qt实现在表格中添加气泡显示功能
Qt在QTableWidget、View等表格中添加右击菜单
Qt网络编程之搭建Udp通信【单播、组播、广播】
Qt设置窗口可拖动
Qt通过QProcess启动进程并传递命令行参数
Qt通过Doc模式读取XML并设计一个增删改查方便的操作类

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林夕07

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值