[QT]2022.4.30 信号和槽的小玩意儿
目录
前言:
信号和槽的自定义
关于自定义信号
自定义信号和槽的重载
信号和信号的连接
拓展
信号槽中的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 信号和槽的小玩意儿相关推荐
- Qt编程中的信号和槽机制
Qt编程中的信号和槽机制 在使用自定义类创建一个按钮之后,只能看到一个按钮的图形,但是使用鼠标点击并无任何反应,下面想要实现一个"点击按钮可以关闭窗口"的功能. 关闭窗口的功能可以 ...
- QT的核心机制信号和槽、QT三大护法
1.QT 三大护法 Qapplication:控制程序执行流程 QWidget:是所有界面组件类的父类,用来绘制界面 QLayout: 是一个布局管理器,可以用来设置窗口中组件的摆放方式 2.如何把信 ...
- Python Qt GUI设计:信号与槽的使用方法(基础篇—7)
目录 1.信号与槽的概念 2.信号与槽的基础函数 2.1.创建信号函数 2.2.连接信号函数 2.3.断开信号函数 2.4.发射信号函数 3.信号和槽的使用方法 3.1.内置信号与槽的使用 3.2.自 ...
- Qt多线程中的信号与槽
文章目录 1 多线程中的信号与槽 2 对象的依附性 2.1 对象的依附性 2.2 开启线程事件循环 2.3 线程事件循环的结束 2.4 设计实例 3 信号与槽的连接方式 3.1 Qt::DirectC ...
- Qt修炼手册4_信号与槽
1.前言 为了处理个体间的通信事件,Qt提供了信号与槽.信号与槽不仅可以处理GUI上发生的事件,也可以实现个体间的数据通信.值得深入把握. 2.信号与槽 信号与槽是一种用于对象间通信的机制.为了用户在 ...
- QT对象树、信号和槽机制
文章目录 一 .对象树是什么? 二.信号和槽的基本概念 2.1 信号 2.2 槽 2.3 松散耦合 2.4 特点 三.示例 总结 一 .对象树是什么? 对象树是由父类和若干子类对象组成,而子类也可以由 ...
- Qt线程间通信-信号与槽通信
线程间通信: 1.自定义事件:postEvent(): 2.信号与槽[本质也是通过自定义事件实现的] 注意:每个线程都有自己的事件循环 下面先说明下信号与槽的通信: 下面这个程序的运行截图 模拟下载! ...
- Qt工作笔记-使用信号与槽让两个界面进行数据通信
今天在项目中,发现有一个十分重要的功能,就是2个界面进行数据通信. 记得1年多前,刚刚学习Qt,对这个无法理解,然后经过一年多的学习和理解,在此把自己学习的感悟和知识在此总结下. 下面是使用emit ...
- QT学习小结之信号与槽
信号与槽函数是我们学习QT必备的基础知识,今天跟大家分享我学习QT的一些总结吧. 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯. 槽函数和普通的C++成员函 ...
最新文章
- R语言使用ggpubr包的ggarrange函数组合多张结论图:使用ggpubr包将图像、文本、表格组合在一起展示
- 运行windows live writer时发生“意外错误”
- 接入amazon avs_每日新闻综述:亚马逊将互联网接入推向全球的宏伟计划
- 正反对角线java表示_连接4对角线Win Check
- 谷粒商城基础篇爬坑笔记--No Feign Client for loadBalancing defined以及加载测试失败
- 发行版,distutils,setuptools和distutils2之间的区别?
- 深入理解:面向服务与微服务架构
- Xenu Link Sleuth 简单好用的链接测试工具 使用说明
- 如何用python制作动画电影_用Python制作3D动画
- 一个简单的文本编辑程序源代码
- Ubuntu16.04开启SSH服务
- PM必备:简单、好用、免费的项目管理软件推荐
- JS内置对象及其用法总结
- web直传cos(腾讯云)图片视频
- CSS高级属性之 box-shadow 详解
- 【Bug解决】Could not find resource com/kuang/mapper/Mapper.xml
- 中小学不得在校内设置食品经营场所,量子摩尔定律问世,美团运营摩拜亏45亿,英伟达史上最大手笔收购,这就是今天的大新闻。...
- 什么是Java语言?java语言简介
- VS2010添加资源文件
- 虚拟机当服务器的设置,虚拟机当作设置服务器