信号槽机制和自定义信号和槽

信号槽和机制

情景带人:

我们都知道鸿门宴,其中项羽想要杀刘邦,就在洪门设宴,并和手下兄弟约定只要项羽摔杯,就从进去绑了刘邦;
在这里插入图片描述

建立:信号和槽函数的关系使用connect

connect(信号的发起者,信号,接受者,操作);

案例:

widget的构造函数中:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //设置窗口标题
    this->setWindowTitle("信号");
    //设置窗口大小
    this->resize(800,600);
    //创建一个按钮
    QPushButton *btn1=new QPushButton("关闭",this);
    //需求:单击btn1 关闭主窗口
    //信号的发起者btn1 发出信号   主窗口this  关闭(槽函数)
    connect(btn1, &QPushButton::clicked, this, &QWidget::close);


    //lambda表达式
    QPushButton *btn2 =new QPushButton("戳我呀",this);
    btn2->move(400,300);
    connect(btn2, &QPushButton::clicked, [=](){
        //获取按钮上的文本
        QString text = btn2->text();
        qDebug()<<text <<endl;

        //设置按钮的文本
        btn2->setText("戳你咋地?");
    } );
}

运行结果:
在这里插入图片描述

自定义信号和槽(了解)

老师—>饿了信号 学生—>请老师吃饭
设计两个类:老师类 学生类

注意:

1、定义信号的规则:在signals下方返回值类型为void 只需声明 不用实现 可以有参数 可以重载

2、定义槽函数的规则:public slots:返回值类型为void 需要声明 需要实现 可以有参数 可以重载

3、用户可以使用emit 发出信号

emit tea->hungry();

在这里插入图片描述

案例:

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
    //返回值类型为void  需要声明 需要实现  可以有参数 可以重载
    void treat();
    void treat(QString foodName);
};

#endif // STUDENT_H

student.cpp

#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{

}

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

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

teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>
#include<QString>
class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = 0);

signals://自定义信号函数
    //定义信号的规则:返回值类型void 只需声明  不用实现  可以有参数 可以重载
    void hungry();
    void hungry(QString foodName);
public slots://自定义槽函数
};

#endif // TEACHER_H

teacher.cpp

#include "teacher.h"

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

widget构造函数:

#include "widget.h"
#include"teacher.h"
#include"student.h"
#include<QPushButton>
#define N 0
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //设置主窗口大小
    this->resize(800,600);
    //实例化一个老师
    Teacher *tea = new Teacher(this);
    //实例化一个学生
    Student *stu = new Student(this);
#if N
    //connect建立老师和学生的关系
    void (Teacher:: *p1)() = &Teacher::hungry;
    void (Student:: *p2)() = &Student::treat;
    connect(tea,p1, stu, p2);
#else
    //报错的原因:hungry信号被重载了
    //通过函数指针 明确那个信号
    void (Teacher:: *p1)(QString foodName) = &Teacher::hungry;
    void (Student:: *p2)(QString foodName) = &Student::treat;
    connect(tea,p1, stu, p2);
#endif
    //下课了 老师饿了
    QPushButton *btn = new QPushButton("下课", this);
    connect(btn,&QPushButton::clicked,[=](){
#if N
        //下课函数:让老师发出饿的信号
        emit tea->hungry();
#else
        //下课函数:让老师发出饿的信号
        emit tea->hungry("锅包肉");
#endif
    });
    
}

Widget::~Widget()
{

}

在这里插入图片描述

总结:

1、一个信号可以和多个槽相连

如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。

2、多个信号可以连接到一个槽

只要任意一个信号发出,这个槽就会被调用。

3、一个信号可以连接到另外的一个信号

当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。

4、槽可以被取消链接

这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。

5、Qt4版本的信号槽写法

connect(tea,SIGNAL(hungry()), stu, SLOT(treat()));

6、Qt5版本的信号槽写法

connect(tea, &Teacher::hungry, stu, &Student::treat);

综合案例(窗口切换)

在这里插入图片描述

创建一个窗口类:

类名为:swidget
在这里插入图片描述
在这里插入图片描述
swidget.h

#ifndef SWIDGET_H
#define SWIDGET_H

#include <QWidget>

class SWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SWidget(QWidget *parent = 0);

signals:
    void back();//回退信号
public slots:
};

#endif // SWIDGET_H

swidget.cpp

#include "swidget.h"
#include<QPushButton>
SWidget::SWidget(QWidget *parent) : QWidget(parent)
{
    //设置查询窗口的大小
    this->resize(800,600);
    this->setWindowTitle("查询窗口");

    //定义一个回退按钮
    QPushButton *btn = new QPushButton("back",this);

    //当按下back 就发出一个back信号
    connect(btn,&QPushButton::clicked,[=](){
        emit this->back();
    });
}

widget.cpp

#include "widget.h"
#include <QPushButton>
#include"swidget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(800,600);
    this->setWindowTitle("登录");

    //定义一个查询窗口
    SWidget *s = new SWidget();

    //创建一个下一页的按钮
    QPushButton *btn = new QPushButton("下一页",this);
    connect(btn,&QPushButton::clicked,[=](){
        //当前窗口隐藏
        this->hide();
        //查询窗口显示
        s->show();
    });

    //监测查询窗口s的回退信号
    connect(s,&SWidget::back,[=](){
        //隐藏查询窗口
        s->hide();
        //显示当前窗口
        this->show();
    });

}

Widget::~Widget()
{

}

运行结果:
在这里插入图片描述
在这里插入图片描述

发布了78 篇原创文章 · 获赞 45 · 访问量 9258

猜你喜欢

转载自blog.csdn.net/weixin_43288201/article/details/105312507