5.Qt自定义信号与槽

1.需求

两个类,老师类与学生类。老师在下课时发出饿了信号,学生接受并执行请客吃饭。

2.代码

  1. Teacher类

    #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();
    
    public slots:
    };
    
    #endif // TEACHER_H
    
    #include "teacher.h"
    
    Teacher::Teacher(QObject *parent) : QObject(parent)
    {
    
    }
    
  2. 学生类

    #ifndef STUDENT_H
    #define STUDENT_H
    
    #include <QObject>
    
    class Student : public QObject
    {
        Q_OBJECT
    public:
        explicit Student(QObject *parent = nullptr);
    
    signals:
    
    public slots:
        //早期的槽必须要写到public slots下,高级版本可以写到public下 或者 全局下
        //返回值是void,需要声明也需要实现
        //可以有参数,可以重载
        void treat();
    };
    
    #endif // STUDENT_H
    
    #include "student.h"
    #include <QDebug>
    
    Student::Student(QObject *parent) : QObject(parent)
    {
    
    }
    
    void Student::treat()
    {
        qDebug() << "请老师吃饭";
    }
    
  3. 测试类

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include "teacher.h"
    #include "student.h"
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    private:
        Ui::Widget *ui;
    
        Teacher* th;
        Student* stu;
    
        void classIsOver();
    };
    
    #endif // WIDGET_H
    
    #include "widget.h"
    #include "ui_widget.h"
    
    //Teacher类
    //Student类
    //下课后老师会触发一个信号(饿了),学生响应信号(请客吃饭)
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        //创建一个老师的对象
        this->th = new Teacher();
        //创建一个学生的对象
        this->stu = new Student();
    
        //老师饿了学生请客连接
        connect(th,&Teacher::hungry,stu,&Student::treat);
        //在没有连接前,学生是不会响应的
        classIsOver();
    }
    
    void Widget::classIsOver()
    {
    
        //下课函数,触发后发送老师饿了的信号
        //emit出发信号 qt独有语法
        emit th->hungry();
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    

3.运行结果

在这里插入图片描述

4.小结

  1. 自定义信号需写到signals下
    返回值void,只需要声明,不需要实现
    可以有参数,可以重载
  2. 早期版本的槽必须要写到public slots下,高级版本可以写到public下 或者 全局下
    返回值是void,需要声明也需要实现
    可以有参数,可以重载
  3. 在没有连接connect前,信号发送是不会响应的
  4. emit发送信号,格式emit + 函数

5.重载函数

我们现在重载个函数,看看怎么调用

  1. teacher类更改

    #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);
    
    public slots:
    };
    
    #endif // TEACHER_H
    
  2. Student类更改

    #ifndef STUDENT_H
    #define STUDENT_H
    
    #include <QObject>
    
    class Student : public QObject
    {
        Q_OBJECT
    public:
        explicit Student(QObject *parent = nullptr);
    
    signals:
    
    public slots:
        //早期的槽必须要写到public slots下,高级版本可以写到public下 或者 全局下
        //返回值是void,需要声明也需要实现
        //可以又参数,可以重载
        void treat();
    
        //重载
        void treat(QString foodName);
    };
    
    #endif // STUDENT_H
    
    #include "student.h"
    #include <QDebug>
    
    Student::Student(QObject *parent) : QObject(parent)
    {
    
    }
    
    void Student::treat()
    {
        qDebug() << "请老师吃饭";
    }
    
     void Student::treat(QString foodName)
     {
        //输出QString时会包裹上" "
        //可以用foodName.toUtf8().data(),将QString先转成QByteArray(),再转成char*
        //不过我这里出了点问题,有了个空格
        qDebug() << "请老师吃饭,吃的是" << foodName.toUtf8().data();
        //用+连接会把整个字符串包裹" ",再输出
        qDebug() << "请老师吃饭,吃的是" + foodName;
     }
    
  3. 测试函数

    #include "widget.h"
    #include "ui_widget.h"
    
    
    
    //Teacher类
    //Student类
    //下课后老师会触发一个信号(饿了),学生响应信号(请客吃饭)
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        //创建一个老师的对象
        this->th = new Teacher();
        //创建一个学生的对象
        this->stu = new Student();
    
        //重载连接,需要用到函数指针,指向明确的函数地址
        //无参函数连接
        void(Teacher::* teacherSignal0)() = &Teacher::hungry;
        void(Student::* studentSlot0)() = &Student::treat;
        connect(th,teacherSignal0,stu,studentSlot0);
        //有参连接
        void(Teacher::* teacherSignal)(QString) = &Teacher::hungry;
        void(Student::* studentSlot)(QString) = &Student::treat;
        connect(th,teacherSignal,stu,studentSlot);
    
        classIsOver();
    }
    
    void Widget::classIsOver()
    {
    
        //下课函数,触发后发送老师饿了的信号
        emit th->hungry();
        emit th->hungry("昏睡红茶");
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
  4. 运行结果
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值