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
    评论
下面是一个简单的QSignalMapper使用案例: ```cpp #include <QtWidgets> class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); QPushButton *button1 = new QPushButton("Button 1", this); QPushButton *button2 = new QPushButton("Button 2", this); QPushButton *button3 = new QPushButton("Button 3", this); layout->addWidget(button1); layout->addWidget(button2); layout->addWidget(button3); QSignalMapper *mapper = new QSignalMapper(this); connect(button1, SIGNAL(clicked()), mapper, SLOT(map())); connect(button2, SIGNAL(clicked()), mapper, SLOT(map())); connect(button3, SIGNAL(clicked()), mapper, SLOT(map())); mapper->setMapping(button1, "Button 1 clicked"); mapper->setMapping(button2, "Button 2 clicked"); mapper->setMapping(button3, "Button 3 clicked"); connect(mapper, SIGNAL(mapped(QString)), this, SLOT(handleButtonClicked(QString))); } private slots: void handleButtonClicked(QString text) { QMessageBox::information(this, "Button clicked", text); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget widget; widget.show(); return app.exec(); } ``` 在上面的代码中,我们创建了三个QPushButton,并将它们添加到一个垂直布局中。然后,我们创建了一个QSignalMapper,并将每个QPushButton的clicked()信号连接到QSignalMapper的map()槽函数上。接着,我们使用QSignalMapper的setMapping()函数将每个QPushButton和一个字符串映射在一起,这个字符串是在按钮被点击时将会传递给槽函数的参数。最后,我们将QSignalMapper的mapped()信号连接到MyWidget的handleButtonClicked()槽函数上,这个槽函数会弹出一个消息框,显示按钮被点击的文本。这样,当任意一个QPushButton被点击时,handleButtonClicked()槽函数就会被调用,并且会显示对应的文本。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林夕07

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

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

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

打赏作者

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

抵扣说明:

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

余额充值