Qt编程基础 | 第二章-信号与槽 | 2.2、自定义信号与槽

一、自定义信号与槽

1.1、实现自定义信号与槽

Qt支持自定义信号,下面声明两个类Student与Teacher类,Teacher类定义hungry信号,Student类提供槽函数,两个类的声明与定义如下:

Teacher类声明

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    // 自定义信号函数
    void hungry();
    void hungry(QString foodName);
};

#endif // TEACHER_H

Student类声明

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
     // 声明两个同名槽函数
     void treat();
     void treat(QString foodName);

};

#endif // STUDENT_H

Student类定义

#include "student.h"
#include <QDebug>

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

void Student::treat()
{
    qDebug() << "treat";
}

void Student::treat(QString foodName)
{
    qDebug() << "treat: " << foodName;
}

信号绑定槽函数及触发信息号

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

    // 登录按键绑定槽函数
    connect(ui->btn_ok, &QPushButton::clicked, this, &MainWindow::login);

    m_pStudent = new Student(this);
    m_pTeacher = new Teacher(this);

    // 1、不带参数的信号与不带参数的槽函数绑定
//    void (Teacher::*pfnTeacherSignal)() = &Teacher::hungry;
//    void (Student::*pfnStudentSlot)() = &Student::treat;

//    connect(m_pTeacher, pfnTeacherSignal, m_pStudent, pfnStudentSlot);

    // 2、带参数的信号与带参数的槽函数绑定
    void (Teacher::*pfnTeacherSignal)(QString) = &Teacher::hungry;
    void (Student::*pfnStudentSlot)(QString) = &Student::treat;

    connect(m_pTeacher, pfnTeacherSignal, m_pStudent, pfnStudentSlot);


}

void MainWindow::login()
{
//    // 触发信号(不带参数的信号)
//    emit m_pTeacher->hungry();

    // 触发信号(带参数的信号)
    emit m_pTeacher->hungry("汉堡");
}

1.2、自定义信号特点

自定义信号时,需要注意下面几点

  • 要使用关键字signals
  • 只需要声明不需要实现
  • 信号函数返回值是void
  • 信号函数可以重载

1.3、触发自定义信号

触发自定义信号需要调用emit函数,如下:

void MainWindow::login()
{
//    // 触发信号(不带参数的信号)
//    emit m_pTeacher->hungry();

    // 触发信号(带参数的信号)
    emit m_pTeacher->hungry("汉堡");
}

二,重载槽函数

槽函数可以重载,Student类定义了两个重载的槽函数,如下:

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

signals:

public slots:
     // 声明两个同名槽函数
     void treat();
     void treat(QString foodName);

};

如何决定具体绑定哪个槽函数?

通过函数指针决定具体绑定哪个槽函数,如下:

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

    // 登录按键绑定槽函数
    connect(ui->btn_ok, &QPushButton::clicked, this, &MainWindow::login);

    m_pStudent = new Student(this);
    m_pTeacher = new Teacher(this);

    // 1、不带参数的信号与不带参数的槽函数绑定
//    void (Teacher::*pfnTeacherSignal)() = &Teacher::hungry;
//    void (Student::*pfnStudentSlot)() = &Student::treat;

//    connect(m_pTeacher, pfnTeacherSignal, m_pStudent, pfnStudentSlot);

    // 2、带参数的信号与带参数的槽函数绑定
    void (Teacher::*pfnTeacherSignal)(QString) = &Teacher::hungry;
    void (Student::*pfnStudentSlot)(QString) = &Student::treat;

    connect(m_pTeacher, pfnTeacherSignal, m_pStudent, pfnStudentSlot);
}

函数重载时可以通过下面三种方法进行绑定
方法一:QOverload

connect(sender, QOverload<bool>::of(&Sender::signal),receiver,
    QOverload<bool>::of(&Receiver::slot));

方法二:函数指针

void (Sender:: * ptr)(int) = &Sender::signal;
void (Receiver:: *rptr)(int) = &Receiver::slot;
connect(sender,ptr,receiver,rptr);

方法三:static_cast

connect(sender, static_cast<void(Sender::*)(bool)>(&Sender::signal),
    receiver, static_cast<void(Receiver::*)(void)>(&Receiver::slot));

三,信号与槽函数类型要匹配

信号与槽函数参数类型要匹配,例如:信号函数带的参数是QString,那么绑定的槽函数要么不带参数(表示不接收数据),要么是跟信号函数一样的参数,下面的代码编译时会报错,因为信号与槽函数参数类型不匹配,如下:

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

    // 登录按键绑定槽函数
    connect(ui->btn_ok, &QPushButton::clicked, this, &MainWindow::login);

    m_pStudent = new Student(this);
    m_pTeacher = new Teacher(this);


    // 信号函数不带参数,槽函数带参数(QString),信号与槽函数参数类型不匹配编译时报错
    void (Teacher::*pfnTeacherSignal)() = &Teacher::hungry;
    void (Student::*pfnStudentSlot)(QString) = &Student::treat;

    QMetaObject::Connection conn = connect(m_pTeacher, pfnTeacherSignal, m_pStudent, pfnStudentSlot);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值