03_信号和槽

信号和槽

  • 系统的信号和槽
  • 自定义信号和槽
  • Lambda表达式

系统的信号和槽

下面我们完成一个小功能,上面我们已经学习了按钮的创建,但是还没有体现出按钮的功能,按钮最大的功能也就是点击后触发一些事情,比如我们点击按钮,就把当前的窗口给关闭掉,那么在Qt中,这样的功能如何实现呢?
其实无法两行代码就可以搞定了,我们看下面的代码

  • QPushButton * quitBtn = new QPushButton(“关闭窗口”,this);
  • connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);

第一行是创建一个关闭按钮,这个之前已经学过,第二行就是核心了,也就是信号槽的使用方式
connect()函数最常用的一般形式:
connect(sender, signal, receiver, slot);
参数解释:

  • sender:发出信号的对象
  • signal:发送对象发出的信号
  • receiver:接收信号的对象
  • slot:接收对象在接收到信号之后所需要调用的函数(槽函数)
    那么系统自带的信号和槽通常如何查找呢,这个就需要利用帮助文档了,在帮助文档中比如我们上面的按钮的点击信号,在帮助文档中输入QPushButton,首先我们可以在Contents中寻找关键字 signals,信号的意思,但是我们发现并没有找到,这时候我们应该想到也许这个信号的被父类继承下来的,因此我们去他的父类QAbstractButton中就可以找到该关键字,点击signals索引到系统自带的信号有如下几个
    在这里插入图片描述

这里的clicked就是我们要找到,槽函数的寻找方式和信号一样,只不过他的关键字是slot。
在这里插入图片描述

    //创建一个自己的按钮对象
    MyPushButton * myBtn=new MyPushButton;
    myBtn->setText("我自己的按钮");

    myBtn->move(200,0);
    myBtn->setParent(this);//设置到对象树中

    //需求 点击我的按钮 关闭窗口
    //参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接收者 参数4 处理的槽函数
    //connect(myBtn,&QPushButton::clicked,this,&Widget::close);
    connect(myBtn,&MyPushButton::clicked,this,&Widget::close);

自定义信号和槽

在这里插入图片描述
在这里插入图片描述

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
    //自定义信号写道signals下
    //返回值是void,只需要声明,不需要实现
    //可以有参数,可以重载
    void hungry();
    void hungry(QString foodName);
};

#endif // TEACHER_H

在这里插入图片描述

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);
    void treat();
    void treat(QString foodName);
signals:
};

#endif // STUDENT_H

使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。
下面我们看看使用 Qt 的信号槽:
首先定义一个学生类和老师类:
老师类中声明信号 饿了 hungry
signals:
void hungury();
学生类中声明槽 请客 treat
public slots:
void treat();
在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
void MyWidget::ClassIsOver()
{
//发送信号
emit teacher->hungury();
}
学生响应了槽函数,并且打印信息
//自定义槽函数 实现
void Student::eat()
{
qDebug() << “该吃饭了!”;
}
在窗口中连接信号槽
teacher = new Teacher(this);
student = new Student(this);

connect(teacher,&Teacher::hungury,student,&Student::treat);

并且调用下课函数,测试打印出 “该吃饭了”

自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name); 自定义信号
void treat(QString name ); 自定义槽
但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (Teacher:: * teacherSingal)(QString) = &Teacher::hungury;
void (Student:: * studentSlot)(QString) = &Student::treat;
connect(teacher,teacherSingal,student,studentSlot);

自定义信号槽需要注意的事项:

  • 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
  • 信号和槽函数返回值是 void
  • 信号只需要声明,不需要实现
  • 槽函数需要声明也需要实现
  • 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
  • 使用 emit 在恰当的位置发送信号;
  • 使用connect()函数连接信号和槽。
  • 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
  • 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
  • 如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

信号槽的拓展

  • 一个信号可以和多个槽相连
    如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
  • 多个信号可以连接到一个槽
    只要任意一个信号发出,这个槽就会被调用。
  • 一个信号可以连接到另外的一个信号
    当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
  • 槽可以被取消链接
    这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
  • 信号槽可以断开
    利用disconnect关键字是可以断开信号槽的
  • 使用Lambda 表达式
    在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。
    在连接信号和槽的时候,槽函数可以使用Lambda表达式的方式进行处理。后面我们会详细介绍什么是Lambda表达式

Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:
capture mutable ->return-type
{
statement
}
函数对象参数mutable ->返回值{函数体}

① 函数对象参数;
[],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:

  • 空。没有使用任何函数对象参数。

  • =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。

  • &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。

  • this。函数体内可以使用Lambda所在类中的成员变量。

  • a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。

  • &a。将a按引用进行传递。

  • a, &b。将a按值进行传递,b按引用进行传递。

  • =,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。

  • &, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。
    ② 操作符重载函数参数;
    标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
    ③ 可修改标示符;
    mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
    QPushButton * myBtn = new QPushButton (this);
    QPushButton * myBtn2 = new QPushButton (this);
    myBtn2->move(100,100);
    int m = 10;

    connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });

    connect(myBtn2,&QPushButton::clicked,this,[=] () { qDebug() << m; });

    qDebug() << m;

④ 函数返回值;
->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
⑤ 是函数体;
{},标识函数的实现,这部分不能省略,但函数体可以为空。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/549566.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

12.哀家要长脑子了!

1.189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; ​ 方法一&#xff1a; 要注意这个k是可以大于0的&#xff0c;所以旋转数组的时候要一直保证是在1-n的范围内&#xff1a;%实现 把k个元素旋转放到前面&#xff0c;前面n-k个元素是向后移动的。 class Solution { …

【Phytium】飞腾D2000 UEFI/EDK2 适配 RTC(IIC SD3077)

文章目录 0. env1. 软件2. 硬件 10. 需求1. 硬件2. 软件 20. DatasheetCPURTC 30. 调试步骤1. 硬件环境搭建2. UEFI 开发环境搭建3. 修改步骤1. UEFI 中使能RTC驱动、配置RTC信息等1.1 使能RTC驱动1.2 修改RTC对应的IIC配置信息1.3 解决驱动冲突1.4 验证波形 2. 修改对应RTC驱动…

[lesson36]经典问题解析三

经典问题解析三 关于赋值的疑问 什么时候需要重载赋值操作符&#xff1f;编译器是否提供默认的赋值操作&#xff1f; 编译器为每个类默认重载了赋值操作符 默认的赋值操作符仅完成浅拷贝 当需要进行深拷贝时必须重载赋值操作符 赋值操作符与拷贝构造函数有相同的存在意义 …

零基础入门测试该学什么?超全整理,照着学就对了!

对于很多小白而言&#xff0c;想要转行软件测试岗位&#xff0c;却又怕自己从来没有接触过计算机&#xff0c;底子很薄弱&#xff0c;从而还没开始就打起了退堂鼓。也有许多初学者&#xff0c;在入门的过程中&#xff0c;苦于不知道该学什么&#xff0c;又该从何学起&#xff0…

代码随想录算法训练营第四十二天| 二维背包、一维背包、LeetCode 416.分割等和子集

一、二维背包 文章讲解/视频讲解&#xff1a;https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 状态&#xff1a;已解决 1.背包问题介绍 背包问题实则是一类问题的集合&#xff0c;有好多不同小类型&#xff0c…

单位优秀信息宣传员告诉你向媒体投稿你不知道的好方法

作为基层社区信息宣传工作队伍中的一员,我刚开始接手单位的信息宣传投稿任务时,真的是一片茫然。没有任何媒体编辑的熟人朋友,我只能硬着头皮,一家家地去联系媒体,沟通投稿的事宜。这个过程真的是既费事又费力,每次投稿都像是在茫茫大海中寻找那一丝被认可的机会。 因为媒体对稿…

VLAN Mapping原理描述

基本原理 路由器收到带Tag的数据报文后&#xff0c;根据配置的VLAN Mapping方式&#xff0c;决定替换外层Tag中的VLAN ID或优先级&#xff1b;然后进入MAC地址学习阶段&#xff0c;根据源MAC地址映射后的VLAN ID刷新MAC地址表项&#xff1b;根据目的MAC映射后VLAN ID查找MAC地…

T细胞耗竭

目录 T Cell Exhaustion T 细胞衰竭路径上的细胞和分子路标 研究起源 介绍 T 细胞耗竭的发生路径 耗尽的T细胞亚群的解剖分离和迁移 持续TCR刺激的收益递减 通过共调节受体进行发育微调 细胞因子介导的耗尽T细胞亚群的特异性 T细胞耗竭和表观遗传 T Cell Exhaustion…

面试问答之转账功能测试点详解

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

快速排序题目SelectK问题

力扣75.颜色分类 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sor…

数据库(mysql)-连接嵌套查询-2

子查询 MySQL中的子查询&#xff08;Subquery&#xff09;是嵌套在其他SQL查询中的查询。子查询可以出现在SELECT、FROM或WHERE子句中&#xff0c;并用于返回将被用于外部查询的数据。子查询的结果可以是一个单一的值、一行、一列或多行多列的数据集。 单行单列查询 实例 #查…

一款挺不错网站维护页面HTML源码

一款挺不错网站维护页面源码&#xff0c;单HTML不需要数据库&#xff0c;上传到你的虚拟机就可以用做维护页面还不错&#xff0c;用处多。。 源码下载 一款挺不错网站维护页面源码

【智能算法】鱼鹰优化算法(OOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2023年&#xff0c;M Dehghani等人受到自然界鱼鹰狩猎行为启发&#xff0c;提出了鱼鹰优化算法&#xff08;Osprey Optimization Algorithm, OOA&#xff09;。 2.算法原理 2.1算法思想 OOA基本灵…

网络爬虫:定义、应用及法律道德考量

网络爬虫技术在当今数据驱动的世界中发挥着重要作用。本文将从网络爬虫的定义和主要功能&#xff0c;其在业界的应用实例&#xff0c;以及涉及的法律和道德问题三个方面进行深入探讨。 1. 爬虫的定义和主要功能 网络爬虫&#xff0c;也称为网页爬虫或蜘蛛&#xff0c;是一种…

苹果与印度深入洽谈,开启新业务 | 百能云芯

印度经济时报&#xff08;ET&#xff09;引述知情人士报导&#xff0c;苹果&#xff08;Apple&#xff09;正和 Murugappa 集团和塔塔集团旗下的Titan公司深入洽谈&#xff0c;将由这两家印度业者组装、甚至生产 iPhone 所用的相机模组。 苹果正将iPhone供应链向中国大陆以外地…

SpringBoot学习(三)数据访问、基础特性、核心原理

文章目录 数据访问示例自动配置原理jdbc场景自动配置数据源等基本信息MyBatisAutoConfiguration配置MyBatis整合流程 基础特性SpringApplication自定义banner自定义SpringApplicationFluentBuilder API Profiles使用指定环境环境激活环境包含 Profiles配置文件 外部化配置配置优…

JVM结构化体系

目录 目录 1.JVM 简介 1.1. 如何理解 JVM 呢&#xff1f; 1.2. 市场主流 JVM 分析&#xff1f; 1.3. 为什么要学习 JVM&#xff1f; 1.4. 字节码底层是如何执行呢&#xff1f; 如何理解 JIT 呢&#xff1f; 为什么 JVM 中解释执行与编译执行的并存&#xff08;混合模式&…

新手教程 | 2024年最新Vmware17安装教程及许可证(详细图文)

目录 前言&#xff1a; 一、VMware Workstation 17 Pro 简介 二、下载安装&#xff08;以Windows为例&#xff09; 三、许可证 四、检查是否安装成功 前言&#xff1a; 重新装电脑后&#xff0c;安装虚拟机 一、VMware Workstation 17 Pro 简介 VMware Workstation 17 …

【JavaWeb】Day46.Mybatis——入门

JDBC介绍 通过Mybatis可以很方便的进行数据库的访问操作。其实java语言操作数据库&#xff0c;只能通过一种方式&#xff1a;使用sun公司提供的 JDBC 规范。Mybatis框架&#xff0c;就是对原始的JDBC程序的封装。 JDBC&#xff1a; ( Java DataBase Connectivity )&#xff0c…

元类的执行

class MetaB(type):def __new__(cls, name, bases, attrs):print(f"使用元类 {cls.__name__} 创建{name}类 ")return super().__new__(cls, name, bases, attrs)class A(metaclassMetaB):passclass C(A):pass元类MetaB的__new__方法应该只会在创建类A时被调用一次, 因…
最新文章