0


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

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

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

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

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

    m_signalMapper =newQSignalMapper(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)));

结果:

在这里插入图片描述
来看一下如果参数为 QObejct是怎么回事

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

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

    StudentInfo* s2 =newStudentInfo("cxq",18);
    StudentInfo* s3 =newStudentInfo("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 转化为我们 自定义的指针

voidQSignalMapperTest::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));

结果:
在这里插入图片描述
完整代码:
ui图
在这里插入图片描述

.h

#pragmaonce#include<QtWidgets/QWidget>#include"ui_QSignalMapperTest.h"#include<QSignalMapper>#include<QDebug>#include<QVariant>#defineQT5typedefstructStudent{
    QString name;int age;}Student;Q_DECLARE_METATYPE(Student)classStudentInfo:publicQObject{
    Q_OBJECT
public:StudentInfo(QObject* parent =nullptr);StudentInfo(QString name,int age, QObject* parent =nullptr);voidSetName(const QString&);
    QString GetName()const;voidSetAge(constint&);intGetAge()const;private:
    QString m_name;int m_age;};classQSignalMapperTest:publicQWidget{
    Q_OBJECT

public:QSignalMapperTest(QWidget *parent = Q_NULLPTR);public Q_SLOTS:voidshowName(const QString&);voidshowName(QString,int);voidshowStrName(QString);voidshowStudentInfo(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 =newQSignalMapper(this);#if1#ifdefQT5
    m_s1.SetName("lion");
    m_s1.SetAge(20);

    StudentInfo* s2 =newStudentInfo("cxq",18);
    StudentInfo* s3 =newStudentInfo("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 =newStudentInfo("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#if0#ifdefQT5
    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}voidQSignalMapperTest::showName(const QString& str){qDebug()<< str;}voidQSignalMapperTest::showName(QString name,int age){qDebug()<<QStringLiteral("姓名:");}voidQSignalMapperTest::showStrName(QString str){qDebug()<< str;}voidQSignalMapperTest::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;}voidStudentInfo::SetName(const QString& name ){
    m_name = name;}

QString StudentInfo::GetName()const{return m_name;}voidStudentInfo::SetAge(constint& age){
    m_age = age;}intStudentInfo::GetAge()const{return m_age;}

参考博客:
QSignalMapper介绍
QSignalMapper使用

标签: qt 笔记 ui

本文转载自: https://blog.csdn.net/lion_cxq/article/details/130276969
版权归原作者 lion_cxq 所有, 如有侵权,请联系我们删除。

“QT笔记——信号转发器之QSignalMapper”的评论:

还没有评论