信号与槽机制

1. 信号与槽机制(重点,但不是难点)

1.1 机制:

是一种两个对象之间的通信的机制

例如:

鼠标双击-------文件夹图标---------打开文件夹功能

通信的过程:

用户对象

文件夹图标对象

鼠标双击,相当于告诉文件夹(即给文件夹一个信号),我现在想要打开你

文件收到信号,就执行打开文件夹的功能

信号:在QT中信号用函数来进行体现

槽:在QT中槽也是用函数来进行体现

1.2 实现两个对象之间的通信:

提前将两个对象进行绑定(类似于成为你的QQ好友)

1.2.1 QT中提供了绑定的函数(方法):

connect函数原型:
connect(对象1,对象1发出的信号,对象2,处理对象1发出的信号);//来自于QObject
connect(对象1,SIGNAL(信号),对象2,SLOT(槽));

1对象1:是一个类的实例化,信号的发出者

2对象1发出的信号:信号,实质上是一个函数,信号是对象1中的函数,信号使用     SIGNAL函数包含

3对象2:是一个类的实例化,信号的接收者

4处理对象1发出的信号:槽,实质上也是一个函数,槽是对象2中的函数,槽使用SLOT 函数包含

QObject中的原型:
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)

1.3 细节重点

(1)connect函数不仅可以绑定一个信号和槽,也能绑定两个信号

(2)多个信号可以绑定同一个槽函数

(3)一个信号可以绑定多个槽,先绑定哪个槽,哪个槽先执行,后绑定后执行

2. 自定义信号与槽

2.1 信号:在类中需要放置在关键字signals下

例如:
		signals:
			信号1;
			信号2;
			......

2.1.1 注意事项:

(1)信号只需要声明,不需要实现

(2)信号的返回值类型是void类型

(3)信号也是可以发生重载

(4)信号的参数个数必须大于等于槽函数的参数个数

2.2 槽:在类中需要放置在关键字slots下

例如:
		slots:
			槽1;
			槽2;
			....

2.2.1 注意事项

(1slots前可以加上修饰符:public、protected、private(与C++中修饰符的作用一致)

(2)槽函数既需要声明,也需要实现

(3)槽函数的返回值类型一般也是设置为void类型

(4)当槽函数的参数与信号的参数一致时,需要满足槽函数的参数类型和信号的参数类型保持一致

2.3 信号的触发:

使用emit关键字对信号进行触发

格式:

emit    信号;//将信号给发送出去

2.4  举例:

2.4.1 练习1

车上的司机,看见红灯亮了之后,车就停下,人过马路

对象1:车

信号:车看见红灯亮了,停下

对象2:人

槽:人就可以过马路

绑定:使用connect函数绑定车和人两个对象

course1

Car.h

#ifndef CAR_H
#define CAR_H

#include <QObject>

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

signals://写在signals以下的函数都是该类的信号函数

    //在qt中信号只需要声明不需要实现
    void car_Stop();//表示该函数是Car类的信号

};

#endif // CAR_H

car.cpp

#include "car.h"

Car::Car(QObject *parent)
    : QObject{parent}
{

}

people.h

#ifndef PEOPLE_H
#define PEOPLE_H

#include <QObject>
#include <QDebug>

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

signals:

public slots://写在slots以下的函数都是该类的槽
    void walk();

};

#endif // PEOPLE_H

people.cpp

#include "people.h"

People::People(QObject *parent)
    : QObject{parent}
{

}

void People::walk(){
    qDebug()<<"人收到车停下的信号,可以过马路"<<endl;
}

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>
#include <QDebug>
#include <car.h>
#include <people.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MyDialog; }
QT_END_NAMESPACE

class MyDialog : public QDialog
{
    Q_OBJECT

public:
    MyDialog(QWidget *parent = nullptr);
    ~MyDialog();

    void emit_Car_Stop_Signal();//发送信号函数

private:
    Ui::MyDialog *ui;

    //实例化方式1
    Car* car = new Car;//实例化车
    People* people = new People;//实例化人

    //实例化方式2
//    Car car;
//    People people;


};
#endif // MYDIALOG_H

mydialog.cpp

#include "mydialog.h"
#include "ui_mydialog.h"

//练习
//    车上的司机,看见红灯亮了之后,车就停下,人过马路
//    对象1:车
//    信号:车看见红灯亮了,停下
//    对象2:人
//    槽:人就可以过马路
//    绑定:使用connect函数绑定车和人两个对象

MyDialog::MyDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::MyDialog)
{
    ui->setupUi(this);

    //向控制台打印消息
//    qDebug()<<"hello world";
//    qDebug("你好,世界");

    //1.先实现人车对象的绑定
    connect(this->car,SIGNAL(car_Stop()),this->people,SLOT(walk()));//SIGNAL()和SLOT()将你传来的参数转为字符串类型


    //2. 在调用信号触发函数
    this->emit_Car_Stop_Signal();


}

//析构
MyDialog::~MyDialog()
{
    delete ui;
}

void MyDialog:: emit_Car_Stop_Signal(){
    //进行信号的触发
    emit this->car->car_Stop();
}


main.cpp

#include "mydialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyDialog w;
    w.show();
    return a.exec();
}

2.4.2 练习2 元旦节发红包

写法1

快到元旦节了,老师给张三发红包,但是老师没张三微信,就先发给李四,让李四转交给张三,张三收到红包后说谢谢老师

course1-1

teacher.h

#define TEACHER_H

#include <QObject>

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

signals:
    //发送红包的信号函数
    void send();

};

#endif // TEACHER_H

teacher.cpp

#include "teacher.h"

Teacher::Teacher(QObject *parent)
    : QObject{parent}
{

}

lisi.h

#ifndef LISI_H
#define LISI_H

#include <QObject>
#include <QDebug>

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

signals:
    void zhuanjiao();//转交红包

public slots:
    void jieshou_zhuanjiao();//接收老师的红包转交给张三

};

#endif // LISI_H

lisi.cpp

#include "lisi.h"

Lisi::Lisi(QObject *parent)
    : QObject{parent}
{

}

void Lisi::jieshou_zhuanjiao(){
    qDebug()<<"lisi代替zhangsan接收到红包,马上转交给zhangsan"<<Qt::endl;
    emit this->zhuanjiao();//转交红包,触发信号触发的是李四的信号
}

zhangsan.h

#ifndef ZHANGSAN_H
#define ZHANGSAN_H

#include <QObject>
#include <QDebug>

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

signals:

public slots://槽
    void xiexie();//谢谢老师

};

#endif // ZHANGSAN_H

zhangsan.cpp

#include "zhangsan.h"

Zhangsan::Zhangsan(QObject *parent)
    : QObject{parent}
{

}
void Zhangsan::xiexie(){
    qDebug()<<"zhangsan接收到lisi转交的红包,并说了:谢谢老师的红包"<<endl;
}

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>
#include <teacher.h>
#include <lisi.h>
#include <zhangsan.h>

QT_BEGIN_NAMESPACE
namespace Ui {
    class Mydialog;
}
QT_END_NAMESPACE

class Mydialog : public QDialog
{
    Q_OBJECT

public:
    Mydialog(QWidget *parent = nullptr);
    ~Mydialog();

    void emit_hongbao_Signal();//发送信号函数


private:
    Ui::Mydialog *ui;


    //实例化对象
    Teacher* tea=new Teacher;
    Lisi* lisi = new Lisi;
    Zhangsan* zhangsan = new Zhangsan;

};
#endif // MYDIALOG_H



mydialog.cpp

#include "mydialog.h"
#include "ui_mydialog.h"


//练习2
//快到元旦节了,老师给张三发红包,但是老师没张三微信,就先发给李四,让李四转交给张三,张三收到红包后说谢谢老师

Mydialog::Mydialog(QWidget *parent): QDialog(parent), ui(new Ui::Mydialog){//构造
    ui->setupUi(this);

    //绑定老师与李四
    connect(this->tea,SIGNAL(send()),this->lisi,SLOT(jieshou_zhuanjiao()));

    //绑定李四与张三
    connect(this->lisi,SIGNAL(zhuanjiao()),this->zhangsan,SLOT(xiexie()));

    //调用信号触发
    this->emit_hongbao_Signal();

}

Mydialog::~Mydialog()
{
    delete ui;
}

void Mydialog:: emit_hongbao_Signal(){
    //进行信号的触发,触发老师的信号
    emit this->tea->send();
}



写法2

course1-2

teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    void Tea_send_Red_Package();//老师发送红包信号
};

#endif // TEACHER_H

teacher.cpp

#include "teacher.h"

Teacher::Teacher(QObject *parent)
    : QObject{parent}
{

}

lisi.h

#ifndef LISI_H
#define LISI_H

#include <QObject>

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

signals:
    void lisi_send_Red_Package();//李四转交信号

};

#endif // LISI_H

lisi.cpp

#include "lisi.h"

Lisi::Lisi(QObject *parent)
    : QObject{parent}
{

}

zhangsan.h

#ifndef ZHANGSAN_H
#define ZHANGSAN_H

#include <QObject>
#include <QDebug>

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

signals:

public slots:
    void receive_Red_Package();//接收红包槽

};

#endif // ZHANGSAN_H

zhangsan.cpp

#include "zhangsan.h"

Zhangsan::Zhangsan(QObject *parent)
    : QObject{parent}
{

}

void Zhangsan::receive_Red_Package(){

    qDebug()<<"谢谢老师"<<Qt::endl;
}

mydialog.h

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>
#include <teacher.h>
#include <lisi.h>
#include <zhangsan.h>

QT_BEGIN_NAMESPACE
namespace Ui { class Mydialog; }
QT_END_NAMESPACE

class Mydialog : public QDialog
{
    Q_OBJECT

public:
    Mydialog(QWidget *parent = nullptr);
    ~Mydialog();

private:
    Ui::Mydialog *ui;

    //实例化对象
    Teacher* tea=new Teacher;
    Lisi* lisi = new Lisi;
    Zhangsan* zhangsan = new Zhangsan;

};
#endif // MYDIALOG_H

mydialog.cpp

#include "mydialog.h"
#include "ui_mydialog.h"

Mydialog::Mydialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Mydialog)
{
    ui->setupUi(this);

    //绑定,在connect中可以绑定两个信号
    connect(this->tea,SIGNAL(Tea_send_Red_Package()),this->lisi,SIGNAL(lisi_send_Red_Package()));

    connect(this->lisi,SIGNAL(lisi_send_Red_Package()),this->zhangsan,SLOT(receive_Red_Package()));
    emit this->tea->Tea_send_Red_Package();//触发信号
}

Mydialog::~Mydialog()
{
    delete ui;
}

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值