目录

前言:

信号和槽的自定义

关于自定义信号

自定义信号和槽的重载

信号和信号的连接

拓展

信号槽中的lamba表达式

总结


前言:

提到信号和槽(Signal & Slot),首先我们来看一个简单的案例来表示两者的应用场景。

case1:人 — 许愿 — 神灯 —出现灯神

case2:老师 — 饿了 — 学生 —请客吃饭

一个简单条件事件抽象出来的过程大概就是信号和槽的过程:

信号发送者 — 发出信号 — 信号接收者 —响应信号

显然信号和槽是两个独立的个体,这时就需要我们用connect关键字彼此对应的 信号和槽 链接起来。

关键字原型: connect(参数1 ,参数2 ,参数3 ,参数4)

四个参数依次对应上面的信号和槽的过程。

发出信号 和 响应信号 需要相应的函数地址(因为需要访问信号主体)。

case:connect(button1 , &QPushButton::clicked , this , &QWidget::close ) ;

松散耦合:信号发送端和接收端没有任何关联,凭借关键字connect将两端耦合在一起,非常灵活。

信号和槽的自定义

关于自定义信号

信号位置:每个头文件的signal下

信号注意点:1.每个类的头文件都有自己的signal 区域

2.返回值void ,只需要声明,不需要实现

3.可以有参数,可以重载

槽位置    :头文件下的 public slot 或 public全局域(5.4版本以上)

槽注意点   :1.返回值void,需要声明,也需要实现(实现通常写在对应cpp源文件)

2.可以有参数,可以重载

窗口位置1.对应窗口的头文件下,要加入信号类和槽类的头文件

                 2.窗口类里声明好 信号类和槽类的 指针,并在源文件对这两个指针初始化(new)

                  3.在窗口类源文件 进行 connect 连接

调用位置:在信号和槽 对应的窗口类中的某一位置(窗口类中,类对象构造时),调用emit 信号触发函数(可以单独用一个函数封装它)。

最后的小case:下课→ [老师—饿了] →  [学生—请吃饭]

(注意:这个case没有发生重载,所以connect可以直接通过函数地址连接。

一旦发生重载,不管我们连接的函数地址是有参还是无参,都需要借用函数指针来连接。)

mywidget.h:#include <QWidget>
#include"teacher.h"   //teacher 老师类
#include"student.h"   //student 学生类
class mywidget : public QWidget
{Q_OBJECTpublic:void classisover();teacher *zt;  //信号和槽类声明student *st;mywidget(QWidget *parent = 0);~mywidget();
};--------------------------------------------------------------
mywidget.cpp//下课,老师 饿了 → 学生 请吃饭
mywidget::mywidget(QWidget *parent)  //默认构造: QWidget(parent)
{this->st = new student(this); //声明信号类 (同时绑定此窗口)this->zt = new teacher(this); //声明槽  类 (同时绑定此窗口)connect(zt,&teacher::hungry,st,&student::treat);// emit zt->hungry();   方法一classisover();
}
void mywidget::classisover()
{emit zt->hungry();
}
----------------------------------------------------------------
student.hclass student : public QObject
{Q_OBJECT
public:explicit student(QObject *parent = nullptr);signals:public slots:void treat();   //槽声明
};
-----------------------------------------------------------------
student.cppvoid student::treat()
{qDebug("学生请吃饭");
}
-----------------------------------------------------------------
teacher.hclass teacher : public QObject
{Q_OBJECT
public:explicit teacher(QObject *parent = nullptr);//这个位置也不错(greater than ↑5.4)
signals:void hungry();  //信号声明
public slots:
};
------------------------------------------------------------------
teacher.cpp 默认

可以看到,信号类管触发(emit)    而   槽类管实现

自定义信号和槽的重载

重载的主要区别是,在connect时,由于函数发生重载,需要我们自己指定函数地址(这时就需要函数指针了)

    void (student::*studentsignal)(QString) = &student::treat;void (teacher::*teachersignal)(QString) = &teacher::hungry;connect(zt,teachersignal,st,studentsignal);

相应的信号触发 :

  emit zt->hungry("宫保鸡丁");

如果要以char*形式 代替QString 输出

void student::treat(QString foodName) qDebug()<<"学生请老师吃"<<foodName.toUtf8().data();
// toUtf8() → QByteArray    .data() → char*

// qDebug()<<"学生请老师吃"<<foodName.toStdString().c_str();     //也可以达到同样效果

信号和信号的连接

主要仰仗connect的连接(类似minecraft 的 红石,电路的逐个连接)。

另外:取消connect连接的关键字:disconnect  参数同理

这里仍然沿用上面的例子。

简单的按钮触发下课情况。
    void (student::*studentsignal)(void) = &student::treat;           
    void (teacher::*teachersignal)(void) = &teacher::hungry;   //无参函数指针
    connect(zt,teachersignal,st,studentsignal);                        //连接 老师饿了 和 学生请客
    QPushButton *pb = new QPushButton("下课",this);          //定义按钮
    connect(pb,&QPushButton::clicked,zt,teachersignal);      //连接 按钮 和 老师饿了

//   完成连接:按钮→老师饿了→学生请客

//有参函数指针
    void (student::*studentsignal)(QString) = &student::treat;
    void (teacher::*teachersignal)(QString) = &teacher::hungry;
    connect(zt,teachersignal,st,studentsignal);
    QPushButton *pb = new QPushButton("下课",this);
    connect(pb,&QPushButton::clicked,this,&mywidget::classisover);

disconnect(pb,&QPushButton::clicked,this,&mywidget::classisover);

void mywidget::classisover() {
emit zt->hungry("宫保鸡丁");   }

从这里可以看出,connect连接信号触发函数,有两种方法:

①通过封装函数访问信号;②利用函数指针访问。

拓展

1.信号可以连接信号 ;

2.一个信号可以连接多个槽函数 ;

3.多个信号可以连接同一个槽函数 ;

4.信号和槽函数的参数类型 必须一一对应 ;

5.信号的参数可以多于槽的参数(在满足4的情况下)。

6.当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽

//关于QT4信号槽的连接

connect(zt, SIGNAL(hungry()) , st ,SLOT(treat()) );

参数直观,但不会进行类型检测(底层是把信号槽函数转为字符串,不会比较))。

信号槽中的lambda表达式

注意:lambda表达式是c++11版本以上的特性,较低版本使用时需要在工程文件中补一句:CONFIG+=c++11

lambda表达式用来定义并创建匿名函数对象来使用。

基本构成:[capture](parameters)mutable-> return-type

{       statement         }

[函数对象参数](操作符重载函数参数) mutable-> 返回值{   函数体  }

 表达式意义:

[capture]

[ ]作为一个标识符,标志着lambda表达式的开始。(不能省略)

capture函数对象参数 会传递给编译器生成的 函数对象类 的 构造函数。

(当然,capture只能用于 lambda表达式的作用范围内 的 局部变量,包括this)

参数表示如下:

① =       包含作用域内所有可见变量 (按值传递)

② &      包含作用域内所有可见变量(按引用传递)

③ 变量a   对a进行值传递

④ &a        对a引用传递

⑤ this    包含函数对象 类里的成员变量

其他:

[=,&a,&b]   针对a,b引用传递 其他参数值传递

[&,     a,  b]   针对a,b值传递,其他参数引用传递

[a,&b]         对a值传递 对b引用传递

(parameters)

没有参数可以省略

字面意思理解,操作符重载函数参数 可以通过 按值传递 和 按引用传递 两种方式 传递参数

mutuble

按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

return-type

int res = [ ]()->int{return 1000;}

函数体{   }

{},标识函数的实现,不能省略。

函数体使lambda表达式非常有可塑性,能够同时进行许多需要触发的接口和操作。

总结

[QT]2022.4.30 信号和槽的小玩意儿相关推荐

  1. Qt编程中的信号和槽机制

    Qt编程中的信号和槽机制 在使用自定义类创建一个按钮之后,只能看到一个按钮的图形,但是使用鼠标点击并无任何反应,下面想要实现一个"点击按钮可以关闭窗口"的功能. 关闭窗口的功能可以 ...

  2. QT的核心机制信号和槽、QT三大护法

    1.QT 三大护法 Qapplication:控制程序执行流程 QWidget:是所有界面组件类的父类,用来绘制界面 QLayout: 是一个布局管理器,可以用来设置窗口中组件的摆放方式 2.如何把信 ...

  3. Python Qt GUI设计:信号与槽的使用方法(基础篇—7)

    目录 1.信号与槽的概念 2.信号与槽的基础函数 2.1.创建信号函数 2.2.连接信号函数 2.3.断开信号函数 2.4.发射信号函数 3.信号和槽的使用方法 3.1.内置信号与槽的使用 3.2.自 ...

  4. Qt多线程中的信号与槽

    文章目录 1 多线程中的信号与槽 2 对象的依附性 2.1 对象的依附性 2.2 开启线程事件循环 2.3 线程事件循环的结束 2.4 设计实例 3 信号与槽的连接方式 3.1 Qt::DirectC ...

  5. Qt修炼手册4_信号与槽

    1.前言 为了处理个体间的通信事件,Qt提供了信号与槽.信号与槽不仅可以处理GUI上发生的事件,也可以实现个体间的数据通信.值得深入把握. 2.信号与槽 信号与槽是一种用于对象间通信的机制.为了用户在 ...

  6. QT对象树、信号和槽机制

    文章目录 一 .对象树是什么? 二.信号和槽的基本概念 2.1 信号 2.2 槽 2.3 松散耦合 2.4 特点 三.示例 总结 一 .对象树是什么? 对象树是由父类和若干子类对象组成,而子类也可以由 ...

  7. Qt线程间通信-信号与槽通信

    线程间通信: 1.自定义事件:postEvent(): 2.信号与槽[本质也是通过自定义事件实现的] 注意:每个线程都有自己的事件循环 下面先说明下信号与槽的通信: 下面这个程序的运行截图 模拟下载! ...

  8. Qt工作笔记-使用信号与槽让两个界面进行数据通信

    今天在项目中,发现有一个十分重要的功能,就是2个界面进行数据通信. 记得1年多前,刚刚学习Qt,对这个无法理解,然后经过一年多的学习和理解,在此把自己学习的感悟和知识在此总结下. 下面是使用emit ...

  9. QT学习小结之信号与槽

    信号与槽函数是我们学习QT必备的基础知识,今天跟大家分享我学习QT的一些总结吧. 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯. 槽函数和普通的C++成员函 ...

最新文章

  1. R语言使用ggpubr包的ggarrange函数组合多张结论图:使用ggpubr包将图像、文本、表格组合在一起展示
  2. 运行windows live writer时发生“意外错误”
  3. 接入amazon avs_每日新闻综述:亚马逊将互联网接入推向全球的宏伟计划
  4. 正反对角线java表示_连接4对角线Win Check
  5. 谷粒商城基础篇爬坑笔记--No Feign Client for loadBalancing defined以及加载测试失败
  6. 发行版,distutils,setuptools和distutils2之间的区别?
  7. 深入理解:面向服务与微服务架构
  8. Xenu Link Sleuth 简单好用的链接测试工具 使用说明
  9. 如何用python制作动画电影_用Python制作3D动画
  10. 一个简单的文本编辑程序源代码
  11. Ubuntu16.04开启SSH服务
  12. PM必备:简单、好用、免费的项目管理软件推荐
  13. JS内置对象及其用法总结
  14. web直传cos(腾讯云)图片视频
  15. CSS高级属性之 box-shadow 详解
  16. 【Bug解决】Could not find resource com/kuang/mapper/Mapper.xml
  17. 中小学不得在校内设置食品经营场所,量子摩尔定律问世,美团运营摩拜亏45亿,英伟达史上最大手笔收购,这就是今天的大新闻。...
  18. 什么是Java语言?java语言简介
  19. VS2010添加资源文件
  20. 虚拟机当服务器的设置,虚拟机当作设置服务器

热门文章

  1. 阿里云混合云管理平台多Region架构
  2. 2021-08-29bugku做题记录20——贝斯家族
  3. 《程序员》10月刊内容抢先预览:IE 8引爆浏览器大战
  4. 【Linux 一次性计划任务 at】
  5. Pandas中loc和iloc函数用法详解(源码+实例)
  6. 基于Java+uniapp微信小程序的购物商城系统设计与实现
  7. Win11 桌面图标突然无法点击如何解决
  8. Fiddler实现弱网的测试
  9. CSS 3.0实现炫酷发光特效
  10. java下载文件名称各种浏览器兼容问题