该类收集一组无参数的信号,并使用与发送信号的对象对应的整数、字符串或对象参数重新发出它们。在大多数情况下,可以使用lambdas将自定义参数传递给槽。这样成本更低,并且可以简化代码。
该类支持使用setMapping()
将特定字符串、整数、对象和小部件映射到特定对象。
然后,对象的信号可以连接到map()
插槽,该插槽将发出一个与原始信号对象相关的值的信号(可以是mappedInt()
, mappedString()
和mappedObject()
)。最后可以使用removemaps()
删除映射。
该类主要有以下三个信号可以进行绑定,这取决于你使用setMapping()
时传入的标识类型。
void mappedInt(int i)
void mappedObject(QObject *object)
void mappedString(const QString &text)
对象的信号可以关联到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);
}
上述的实例场景可能都有点勉强,但是实际工作中,使用的场景很多,例如功能区的按钮,弹窗类的按钮需要根据自身的大小放到对应的位置,正常情况下·,你可能就会写很多个槽进行实现,虽然可能不完全一样,但是逻辑都是相同的,代码看着也冗余。