当前位置: 首页 > news >正文

Qt_自定义信号

目录

1、自定义信号的规定

2、创建自定义信号

3、带参数的信号与槽 

4、一个信号连接多个槽 

5、信号与槽的断开 

结语


前言:

        虽然Qt已经内置了大量的信号,并且这些信号能够满足大部分的开发场景,但是Qt仍然允许开发者自定义信号,给开发者提供了足够的DIY设计空间。

1、自定义信号的规定

        Qt中的信号实际上就是函数,因此自定义信号本质就是自定义函数,只不过自定义信号函数的写法要遵循以下三点:

        1、Qt提供了关键字“signals”,自定义信号函数必须写在 “signals” 关键字下边。

        2、自定义信号函数只需要声明,不需要实现,返回值要为void。

        3、自定义信号函数可以有形参,允许重载。

        当然,有了自定义信号函数后还需要拥有将该信号发出的能力,可以使用emit关键字修饰信号函数,表示发送该信号。"emit" 是⼀个空的宏。

2、创建自定义信号

        有了上述的规则后,可以手动创建一个自定义信号,并给该信号连接一个槽函数,槽函数内打印一条语句,运行代码后若输出窗口中打印出了语句说明自定义信号成功创建,具体代码如下。

        1、widget.h的代码如下:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTsignals:void mySignal();//自定义信号public:Widget(QWidget *parent = nullptr);~Widget();void Print();//槽函数声明private:Ui::Widget *ui;
};
#endif // WIDGET_H

         2、widget.cpp的代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QDebug>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::Print);//连接信号与槽emit mySignal();//发送信号
}Widget::~Widget()
{delete ui;
}void Widget::Print()
{qDebug()<<"自定义信号调用的自定义槽函数";
}

        运行结果:

        从结果可以看到,槽函数里的语句被打印,说明自定义信号成功被触发且执行了对应的槽函数。 

3、带参数的信号与槽 

        Qt中的信号与槽在代码的层面上都是函数,既然是函数所以他们都可以有形参,不过严格规定信号的参数要与连接的槽的参数类型保持一致,信号的参数多于槽参数都是可以的。当发送该信号时,调用信号所传的实参会传给信号函数的形参,然年信号函数再传递给槽函数,示意图如下:

        代码实现如下,1、widget.h的代码如下:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTsignals:void mySignal(QString s);//自定义信号public:Widget(QWidget *parent = nullptr);~Widget();void Print(QString s);//槽函数声明private:Ui::Widget *ui;
};
#endif // WIDGET_H

        2、widget.cpp的代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QDebug>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::Print);//连接信号与槽emit mySignal("这是一个带有参数的信号");//发送信号
}Widget::~Widget()
{delete ui;
}void Widget::Print(QString s)
{qDebug()<<s;
}

        测试结果:

4、一个信号连接多个槽 

        上述的例子中是一个信号连接一个槽函数,因此当发送该信号时会调用一次槽函数。那么当一个信号连接多个槽函数时,发送该信号时具体的调用方式是什么呢?代码测试如下。

         1、widget.h的代码如下:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTsignals:void mySignal(QString s);//自定义信号public:Widget(QWidget *parent = nullptr);~Widget();void Print(QString s);//槽函数声明1void Print2(QString s);//槽函数声明2private:Ui::Widget *ui;
};
#endif // WIDGET_H

        2、widget.cpp的代码如下:

#include "widget.h"
#include "ui_widget.h"#include <QDebug>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,&Widget::mySignal,this,&Widget::Print);//连接信号与槽connect(this,&Widget::mySignal,this,&Widget::Print2);//连接信号与槽emit mySignal("这是一个带有参数的信号");//发送信号
}Widget::~Widget()
{delete ui;
}void Widget::Print(QString s)
{qDebug()<<s+"槽函数1";
}void Widget::Print2(QString s)
{qDebug()<<s+"槽函数2";
}

        测试结果:

        结果是当一个信号连接多个槽时,发送该信号会调用所有连接的槽的函数,侧面也反映出不仅仅是一个信号可以连接多个槽,一个槽也可以被多个信号连接,只不过这种方式的逻辑就和单个信号连接单个槽的逻辑一样,这里就不再展示代码了

5、信号与槽的断开 

        使⽤disconnect函数即可完成断开,disconnect的⽤法和connect相似,disconnect的形参和connect是一样的,即连接的逻辑和断开的逻辑是一样的。比如在上述代码中,一个信号连接了两个槽函数,使用disconnect函数断开与其中一个槽函数的连接,那么发送信号时只会执行一个槽函数,测试结果如下:

        从结果可以看到,只执行了一个槽函数。 

结语

        以上就是关于自定义信号的讲解,自定义信号虽然用的不多,但是其延申出来的知识可以帮助我们进一步理解信号与槽的细节。 

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!   

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • QT+OSG+OSG-earth如何在窗口显示一个地球
  • 【在Linux世界中追寻伟大的One Piece】五种IO模型和阻塞IO
  • play-with-docker使用指南
  • redis集群创建问题处理
  • 数据结构-3.3.栈的链式存储实现
  • PCL 计算点云距离
  • Python 入门教程(4)数据类型 | 4.6、列表
  • Oracle从入门到放弃
  • Halo 开发者指南——项目运行、构建
  • AI绘画:科技赋能艺术的崭新时代
  • CAPL_构建基于UDS的刷写学习—01 Hex文件的解析
  • 详细介绍 Redis 列表的应用场景
  • Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
  • xml重点笔记(尚学堂 3h)
  • zookeeper向管控平台上报状态
  • [译] React v16.8: 含有Hooks的版本
  • C++11: atomic 头文件
  • Druid 在有赞的实践
  • FineReport中如何实现自动滚屏效果
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Making An Indicator With Pure CSS
  • python学习笔记-类对象的信息
  • TCP拥塞控制
  • 理清楚Vue的结构
  • 强力优化Rancher k8s中国区的使用体验
  • 使用agvtool更改app version/build
  • 使用SAX解析XML
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 阿里云移动端播放器高级功能介绍
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​MySQL主从复制一致性检测
  • #### go map 底层结构 ####
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • $forceUpdate()函数
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (安卓)跳转应用市场APP详情页的方式
  • (二)Linux——Linux常用指令
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (全注解开发)学习Spring-MVC的第三天
  • (三)模仿学习-Action数据的模仿
  • (十二)Flink Table API
  • (四)Controller接口控制器详解(三)
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (转)Oracle存储过程编写经验和优化措施
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .bashrc在哪里,alias妙用
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net core webapi 大文件上传到wwwroot文件夹
  • .net6 webapi log4net完整配置使用流程
  • .NET6 开发一个检查某些状态持续多长时间的类
  • /dev/sda2 is mounted; will not make a filesystem here!