首页 > 其他分享 >QSignalMapper的使用和使用场景

QSignalMapper的使用和使用场景

时间:2024-03-19 11:12:10浏览次数:30  
标签:场景 函数 button signalMapper QString 信号 使用 QSignalMapper

QSignalMapper的使用和使用场景

 

目录

 

QSignalMapper的使用和使用场景

QSignalMapper类收集了一系列的无参信号,然后使用相对于信号发送者来说的整数、字符串或控件参数来重新发送它们。(一开始没读懂没关系,看完就懂了)

常见场景

其实,该类的一个典型的使用场合是,大量控件都要相应槽函数,而这些槽函数的实现又大致相同。这种情况下,最直接的办法就是仍然为每一个控件的相应信号创建一个槽函数。但这会导致代码的大量重复。此时,我们就可以使用QSignalMapper来实现这种需求。

  1. QSignalMapper类支持使用setMapping()函数将一个特定的整数或字符串和一个特定的对象关联起来。

void QSignalMapper::setMapping

  1. 可以将对象的信号(比如button的clicked)连接到QSignalMapper对象的map()槽函数上,而map()槽函数又会使用与对象相关联的整数或字符串来发送mapped()信号。

  2. 所以,我们只要将我们定义的一个槽函数连接到mapped()信号,即可处理大量相似控件的槽函数。

我们以一个例子来说明。其界面如下:(例子来自csdn第二篇文章,稍微的补充修改)

请仔细看补充的注释。将会对应上面写的三条。
初始化界面的代码如下:

void Widget::InitUi()
{
    names << "宋江" << "卢俊义" << "吴用" << "公孙胜"
          << "关胜" << "林冲" << "秦明" << "呼延灼"
          << "花荣" << "柴进" << "李应" << "朱仝"
          << "鲁智深" << "武松" << "董平" << "张清";
    QGridLayout *gridLayout = new QGridLayout;
    for (int i = 0; i < names.size(); ++i)
    {
        QPushButton *button = new QPushButton(names[i]);
        // 使用setMapping()函数将一个特定的整数或字符串或对象(qt doc截图那些)和一个特定的对象关联起来。
        signalMapper->setMapping(button, names[i]);
        // 这就是可以将对象的信号连接到QSignalMapper对象的map()槽函数上
        connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
        gridLayout->addWidget(button, i / 4, i % 4);
    }
    // 将我们定义的槽函数连接到mapped()信号 // 注意看mapped的写法
    connect(signalMapper, SIGNAL(mapped(QString)),this, SLOT(ShowName(QString)));
    setLayout(gridLayout);
}

其中,names是一个私有的QStringList变量,存储每一个按钮上的文本内容。ShowName()是我们定义的一个槽函数,我们就是让所有按钮的clicked()信号都连接到这个槽函数。在窗口类中声明如下:

public slots:
    void ShowName(QString name);
 
private:
    void InitUi();
 
private:
    Ui::Widget *ui;
    QSignalMapper* signalMapper;
    QStringList names;

ShowName()槽函数的实现如下,简单的弹出一个消息框,显示当前点击的按钮的文本内容:

void Widget::ShowName(QString name)
{
    QMessageBox::information(this, "Name", name);
}

当然,别忘了在构造函数中,调用我们的初始化界面的方法,以及实例化我们的signalMapper对象。如下:

ui->setupUi(this);
    signalMapper = new QSignalMapper(this);
    InitUi();

下面是参考。可看可不看

这篇写的不错,搬运为Markdown了 可以看一下

QSignalMapper类可以看成是信号的翻译和转发器。
它可以把一个无参的信号翻译成带int参数、QString参数、 QObject* 参数或者QWidget *参数的信号,并将之转发。
QSignalMapper类的功能核心是要建立一个从原始信号的object到需要的数据的映射(setMapper函数)。 map()作为QSignalMapper的一个槽函数,将根据setMapping规则转发mapped()信号。
QSignalMapper可将多个有类似处理方式signal用一个slot实现,相当于将N个一对一映射通过集中转换成多对一映射。

例子:有一堆button,可以把clicked()事件放在一个函数里进行处理,只要给button编个号或者给button起个名字就行,这样就不用给每个button写一个slot函数了,方便很多。

//mywidget.h
class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = 0);

signals:

public slots:
    //处理最终信号的槽
    void doClicked(const QString &btnName);

private:
    QSignalMapper *signalMapper;

};
//mywidget.cpp
MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
    QString buttonText = "btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn10";
    QStringList textList = buttonText.split(",");
    signalMapper = new QSignalMapper(this);
    QGridLayout *gridLayout = new QGridLayout;

    for(int i=0; i<textList.size(); ++i)
    {
        //动态创建按钮
        QPushButton *button = new QPushButton(textList[i]);

        //原始信号传递给signalMapper
        connect(button,SIGNAL(clicked()),signalMapper,SLOT(map()));
        //设置signalMapper的转发规则,转发为参数为QString类型的信号,并把textList[i]的内容作为实参传递
        signalMapper->setMapping(button, textList[i]);

        gridLayout->addWidget(button, i/3, i%3);
    }

    //将转发的信号连接到最终的槽函数上
    connect(signalMapper,SIGNAL(mapped(QString)),this,SLOT(doClicked(QString)));

    setLayout(gridLayout);
}

void MyWidget::doClicked(const QString &btnName)
{
    //显示被按下的button名称
    QMessageBox::information(this,"Clicked",btnName+" is clicked !");
}

例子说明:
首先把原始不带参数的信号连接到signalMapper的map()槽函数,这样signalMapper能在第一时间接收到原始信号;
其次调用setMapper方法建立映射关系,告诉signalMapper怎样处理原始信号。这个例子是把原始信号转化为一个带QString参数的信号;
最后接收转化后的带参数信号,这里把转化后的信号与槽函数连接,在槽函数中获得需要数据

映射关系可以通过removeMappings()移除;
setMapping函数的参数只有四种,并且要严格按照格式写入,第一种const QString&,第二种int,第三种QObject*,第四种QWidget *,对于后两种,需要的是他们的子类,则在信号处理的函数里进行类型转化.

参考

https://doc.qt.io/qt-5/qsignalmapper.html#details

https://blog.csdn.net/Amnes1a/article/details/70050788

https://blog.csdn.net/u011125673/article/details/51218196

https://blog.csdn.net/Amnes1a/article/details/70050788

标签:场景,函数,button,signalMapper,QString,信号,使用,QSignalMapper
From: https://www.cnblogs.com/lidabo/p/18082312

相关文章

  • 在Linux中,列出几种常用的Linux备份工具并说明各自的适用场景。
    在Linux中,有多种备份工具可用于不同场景下的数据保护和系统恢复,以下是一些常用的备份工具及其适用场景:tar:适用场景:tar是Linux中最基础的归档工具,广泛应用于创建文件和目录的打包备份。它可以将多个文件或整个目录结构整合成一个单一的.tar文件,并可选地配合gzip、bzip2或xz等......
  • 10分钟教你建一个漂亮大气的网站并立即上线使用
    10分钟教你建一个漂亮大气的网站并立即上线使用需要准备资料:服务器一台,最好有独立Ip,建议购买云服务器域名一个,按国家要求备案。部署简介:我们将采用全界面式的安装。管理服务器采用宝塔基于宝塔安装数据库,安装WordPress配置WordPress模板,编辑页面内容步骤一:在服务器......
  • # Docker安装使用Redis
    拉取最新版本redisdockerpullredis:7.2.4查看镜像dockerimages新建本地挂载配置文件夹(位置随意)1、创建文件夹(位置随意):data、confredis默认配置只能够本地连接、不能进行远程访问需要手动挂载redis配置文件mkdir-p/docker-root/redis_6379/datamkdir-p/d......
  • C++STL第五篇(链表List的使用方法)
    list链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。相......
  • TP6 使用 nusoap为第三方webservice调用插件
    composer下载插件composerrequirenusoap/nusoapuseNuSoap\Client\Client;classIndexextendsBaseController{/****/publicfunctionindex(){//WebService的WSDL地址$wsdl='http://xxx.ygys.net/ResumeServ......
  • node 使用 redlock 分布式锁
    'usestrict';constService=require('egg').Service;constmoment=require('moment');constredis=require('redis');constRedlockClass=require('redlock');const{port,host,password}=require(&#......
  • 使用Proxifier玩转代理
    使用Proxifier玩转代理Proxifier介绍​Proxifier​是一款代理客户端软件,可以让不支持代理服务器工作的程序变的可行。支持各种操作系统和各代理协议,它的运行模式可以指定端口,指定程序的特点。​Proxifier​的主要用途是在系统级别通过代理服务器强制Web请求,从而使来自不支......
  • Tauri 使用
    首先确保安装了Cargo:https://www.rust-lang.org/tools/install官网:https://tauri.app/v1/guides/getting-started/setup安装:cargoinstallcreate-tauri-app--locked创建项目,后面根据你的需要选择对应的选项:cargocreate-tauri-app......
  • MySQL系列:索引失效场景总结
    相关文章数据库系列:MySQL慢查询分析和性能优化数据库系列:MySQL索引优化总结(综合版)数据库系列:高并发下的数据字段变更数据库系列:覆盖索引和规避回表数据库系列:数据库高可用及无损扩容数据库系列:使用高区分度索引列提升性能数据库系列:前缀索引和索引长度的取舍数据库系列:My......
  • 如何使用谷歌查询PyPI包下载信息
    AnalyzingPyPIpackagedownloads-PythonPackagingUserGuide下面是英文官网原文,解释了为什么不能获取下载统计信息。 翻译过后主要有以下几个原因:1、使用CDN效率低:下载信息是动态变化的。包含在项目中的话,大量缓存会使得降低效率。2、数据不精准:下载信息不可能准确无......