一、什么是信号和槽?
我们经常看到的功能,点击一个按钮实现窗口关闭。
这一过程发生了什么?是怎么实现的
按钮相当于一个信号,点击相当于发送一个信号,窗口是个接收者,关闭窗口是个槽函数
信号:各种事件
槽:响应信号的动作
当一个按钮(信号)被触发(发送的信号),某个信号接收到(信号的接收者)就会做出相应的处理动作(槽函数)。他们是怎么建立连接的呢?要想实现这功能我们需要应用到这个api connect()来建立他们四者的关系。
二、connect的实现以及demo实例
1.连接函数 connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
参数说明:
参数1:信号的发送者
参数2:发送的信号(函数地址)
参数3:信号的接受者
参数4:处理的槽函数(函数的地址)
实现一个按下按钮关闭窗口的demo
#include"widget.h"#include"ui_widget.h"#include<QPushButton>Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//重置窗口大小resize(600,400);//创建一个按钮
QPushButton *btn =newQPushButton("按钮",this);//设置到对象树中
btn->setParent(this);//移动按钮
btn->move(100,50);//点击我的按钮,关闭窗口connect(btn,QPushButton::clicked,this,QWidget::close);}Widget::~Widget(){delete ui;}
2、松散耦合
信号和槽的优点:松散耦合,信号的发送端和接收端本身是没有关联的,通过connect连接,将两端耦合在一起。
三、自定义信号和槽
3.1、自定义信号实现说明
1、写到signal下
2、返回void
3、需要声明,不需要实现
4、可以有参数,可以重载
3.2、自定义的槽函数实现说明
1、返回void
2、需要声明,也需要实现
3、可以有参数,可以重载
4、可以写到public slot下或者public或者全局函数(早期QT版本,必须要写到public slots,高级版本可以写到public或者全局函数)
1.自定义一个信号和槽函数demo实现:下课了,小明触发一个信号,想去打游戏,小张响应信号,一起打王者
//创建两个类,Ming,Zhang 基类是QObject
widget.cpp
#include"widget.h"#include"ui_widget.h"#include<QPushButton>Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//创建一个小明对象this->xm =new Ming;//创建一个小张对象this->xz =new Zhang;connect(xm,Ming::playGame,xz,Zhang::playLol);classIsOver();}//封装一个下课函数,调用emit触发玩游戏的信号voidWidget::classIsOver(){
emit xm->playGame();}
widget.h
#ifndefWIDGET_H#defineWIDGET_H#include"zhang.h"#include"ming.h"#include<QWidget>namespace Ui {classWidget;}classWidget:publicQWidget{
Q_OBJECT
public:explicitWidget(QWidget *parent =0);~Widget();private:
Ui::Widget *ui;
Ming *xm;
Zhang *xz;voidclassIsOver();};#endif// WIDGET_H
ming.h
#ifndefMING_H#defineMING_H#include<QObject>classMing:publicQObject{
Q_OBJECT
public:explicitMing(QObject *parent =0);
signals:voidplayGame();public slots:};#endif// MING_H
zhang.h
#ifndefZHANG_H#defineZHANG_H#include<QObject>classZhang:publicQObject{
Q_OBJECT
public:explicitZhang(QObject *parent =0);
signals:public slots:voidplayLol();};#endif// ZHANG_H
zhang.cpp
#include"zhang.h"#include<QDebug>Zhang::Zhang(QObject *parent):QObject(parent){}voidZhang::playLol(){qDebug()<<"一起打王者";}
2.自定义带参一个信号和槽函数demo实现:下课了,小明触发一个信号,想去打游戏,小张响应信号,一起打王者,角色是安琪拉
//创建两个类,Ming,Zhang 基类是QObject
widget.cpp
#include<QPushButton>Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);//创建一个小明对象this->xm =new Ming;//创建一个小张对象this->xz =new Zhang;//用函数指针传递函数地址void(Ming::*mingSignal)(QString)= Ming::playGame;void(Zhang::*zhangSignal)(QString)= Zhang::playLol;connect(xm,mingSignal,xz,zhangSignal);classIsOver();}//封装一个下课函数,调用emit触发玩游戏的信号voidWidget::classIsOver(){
emit xm->playGame("安琪拉");}Widget::~Widget(){delete ui;}
widget.h
#ifndefWIDGET_H#defineWIDGET_H#include"zhang.h"#include"ming.h"#include<QWidget>namespace Ui {classWidget;}classWidget:publicQWidget{
Q_OBJECT
public:explicitWidget(QWidget *parent =0);~Widget();private:
Ui::Widget *ui;
Ming *xm;
Zhang *xz;voidclassIsOver();};#endif// WIDGET_H
ming.h
#ifndefMING_H#defineMING_H#include<QObject>classMing:publicQObject{
Q_OBJECT
public:explicitMing(QObject *parent =0);
signals:voidplayGame(QString roleName);public slots:};#endif// MING_H
zhang.h
#ifndefZHANG_H#defineZHANG_H#include<QObject>classZhang:publicQObject{
Q_OBJECT
public:explicitZhang(QObject *parent =0);
signals:public slots:voidplayLol(QString roleName);};#endif// ZHANG_H
zhang.cpp
#include"zhang.h"#include<QDebug>Zhang::Zhang(QObject *parent):QObject(parent){}voidZhang::playLol(QString roleName){qDebug()<<"一起打王者,角色:"<<roleName.toUtf8().data();}
*四、QString 转char ***
//QString转char方法:先转成QByteArray(.toUtf8()) .data()再转char*
qDebug()<<"打王者,角色是:"<<roleName.toUtf8().data();}
五、信号和槽之间的关系
1、信号可以连接信号
2、信号可以连接多个信号
3、一个信号可以连接多个槽
4、多个信号可以连接同一个槽
5、信号和槽的参数一一对应
6、信号和槽的参数个数 是不是要一致?未必,信号的参数个数可以多于槽函数的参数个数
六、Lambda表达式
C++中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。
1.[]标识符 匿名函数
2.= 值传递
3.&引用传递
4.()参数
5.{}实现体
6.mutable修饰值传递变量,可以修改拷贝出的数据,改变不了本体
7.返回值[M]->int []
利用lambda表达式,实现点击按钮关闭窗口的demo
#include"widget.h"#include"ui_widget.h"#include<QPushButton>#include<QDebug>Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
ui->setupUi(this);resize(600,400);//创建一个按钮
QPushButton *btn =newQPushButton("按钮",this);//设置到对象树中
btn->setParent(this);//移动按钮
btn->move(100,50);//点击我的按钮,关闭窗口connect(btn,QPushButton::clicked,this,[=](){this->close();qDebug()<<"窗口关闭";});}Widget::~Widget(){delete ui;}
版权归原作者 柠檬你个思密达i! 所有, 如有侵权,请联系我们删除。