Qt信号槽机制详解及案例

目录

信号槽

标准信号槽

自定义信号槽


信号槽

信号槽是Qt框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出的信号是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
connect(sender,signal,receiver,slot);

  •   sender:发出信号的对象
  • signal:发送对象发出的信号(函数地址)
  • receiver:接收信号的对象
  • slot:接收对象在接收到信号之后所需要调用的槽函数地址

优点:
松散耦合:信号的发送端和信号的接收端本身是没有关联的,通过connect函数将两端耦合在一起。

标准信号槽

练习:点击按钮关闭窗口

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)  //调用父类构造函数
{
    //创建一个按钮
    QPushButton *btn = new QPushButton;
    //btn->show(); //以顶层方式弹出窗口控件
    //让btn依赖在myWidget窗口中
    btn->setParent(this); //this指当前窗口
    btn->setText("关闭");
    btn->move(100,100);
    //点击按钮关闭窗口
    //参数1:信号发送者 参数2:发送的信号(函数地址) 参数3:信号接收者 参数4:处理槽函数地址
    connect(btn,&QPushButton::clicked,this,&QWidget::close);

}

myWidget::~myWidget()
{
    
}

这里的clicked按钮中的标准信号,close关闭窗口函数是标准槽函数。

自定义信号槽

当Qt提供的信号和槽函数无法满足需求时,就需要用到自定义信号槽,使用emit来发出信号。

练习:定义老师和学生类继承QWidget,老师发出下课信号,学生响应请吃饭

teache.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    //自定义信号,写道signals下
    //返回值时void,秩序申明,不需要实现
    //可以有参数,可以重载
    void hangry();

public slots:

};

#endif // TEACHER_H

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
//    早期Qt版本需要写到public slots下,高级版本可以写到public或全局下
//    返回值为void,需要声明,也需要实现
//    可以有参数,可以发生重载
    void treat();

};

#endif // STUDENT_H

student.cpp

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

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

}

void Student::treat()
{
    qDebug()<<"请老师吃饭";
}

widget.h

#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 = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    Teacher *te;
    Student *st;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

//Teacher类
//Student类
//下课后 老师会触发一个信号,饿了,学生响应信号,请客吃饭
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建老师对象
    this->te = new Teacher(this);
    //创建学生对象
    this->st = new Student(this);
    //连接老师和学生
    connect(te,&Teacher::hangry,st,&Student::treat);
    //发出信号
    emit te->hangry();

}

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

信号槽的重载

重载的信号槽,需要构造信号和槽函数对应的重载函数的指针,让信号在连接时可以找到对应的重载函数。

练习:定义老师和学生类继承自QWidget,老师发出下课信号,饿了,想吃宫保鸡丁,学生响应请老师吃宫保鸡丁。

在teacher.h中增加有参的信号

void hangry(QString foodName);

在student.h中增加有参的槽函数

void treat(QString foodName);

在student.cpp中实现带参数的重载槽函数

void Student::treat(QString foodName)
{
    //qDebug打印Qstring时带引号,转为char *就不带引号、、
    //转换:先转成QByteArrey,再转char * ->foodName.toUtf8().data()

    qDebug()<<"请老师吃:"<<foodName.toUtf8().data();
}

在widget.cpp中连接信号槽

//连接重载的信号和槽
//指针 -> 指向地址
//函数指针 -> 指向函数的指针
void(Teacher:: *teacherSignal)(QString) = &Teacher::hangry;
void(Student:: *studentSlot)(QString) = &Student::treat;
connect(te,teacherSignal,st,studentSlot);
//发出信号
emit te->hangry("宫保鸡丁");

可以用disconnect()函数取消信号的槽连接。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值