Qt信号和槽

21 篇文章 0 订阅

 一、定义

信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。

信号(Signal)就是在特定情况下被发射的事件,例如 PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的CurrentIndexChanged() 信号。

GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。

槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

信号与槽关联是用 QObject::connect() 函数实现的:

  connect(btn,&QPushButton::clicked,this,&QWidget::close);
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
//    第一个按钮
    QPushButton * btn=new QPushButton;
    //show以顶层方式弹出窗口坤健
//    btn->show();
    //让队形依赖于widget窗口
    btn->setParent(this);
    //显示文本
    btn->setText("关闭按钮");
//    创建第二个按钮,按照按钮的大小创建窗口
    QPushButton * btn2=new QPushButton("第二个按钮",this);

    btn2->move(100,100);
//    重置窗口大小
    resize(600,400);
//    设置固定窗口大小
    setFixedSize(600,400);
//    设置窗口标题
    setWindowTitle("第一个窗口");
     //需求,点击关闭按钮,关闭窗口
    //参数1:信号发送者 参数2:发送的信号 参数3:信号接受者 参数4:处理的槽函数
    connect(btn,&QPushButton::clicked,this,&QWidget::close);
}

二、自定义信号和槽

//Teacher类 老师类
//Student类 学生类
//下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭

 依次创建teacher和student类

 

  1、自定义信号

teacher.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 hungry();
};

#endif // TEACHER_H

teacher.cpp


#include "teacher.h"

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

}

2、自定义槽

student.h


#ifndef STUDENT_H
#define STUDENT_H


#include <QObject>


class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);
    //早期Qt版本,必须要写到public slots,高级本本可以写到public或者全局下
    //返回值void,需要申明,也需要实现
    //可以有参数,可以发生重载
    void treat();

signals:

};

#endif // STUDENT_H

student.cpp


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

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

3、关联信号和槽并发送信息

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);
    //创建一个学生对象
    this->st=new Student(this);
    //老师饿了,学生请客的连接
    connect(th,&Teacher::hungry,st,&Student::treat);
    //调用下课函数,触发信号
    classIsOver();
}
void Widget::classIsOver(){
    //下课函数,调用后,触发老师饿了的信号
    emit th->hungry();
}
Widget::~Widget()
{
    delete ui;
}


三、带参数信号和槽

teach.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 hungry();

    void hungry(QString foodName);
};

#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);
    //早期Qt版本,必须要写到public slots,高级本本可以写到public或者全局下
    //返回值void,需要申明,也需要实现
    //可以有参数,可以发生重载
    void treat();

    void treat(QString foodName);

signals:

};

#endif // STUDENT_H

student.cpp


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

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

void Student::treat(QString foodName){
    //QString转换为char *
    qDebug()<<"请老师吃饭,老师要吃"<<foodName.toUtf8().data();
}

widget.cpp


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

//Teacher类 老师类
//Student类 学生类
//下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建一个老师对象
    this->th=new Teacher(this);
    //创建一个学生对象
    this->st=new Student(this);

    //老师饿了,学生请客的连接
//    connect(th,&Teacher::hungry,st,&Student::treat);
    //调用下课函数,触发信号
//    classIsOver();

    //连接带参数的信号和槽
    //指针->地址
    //函数指针->函数地址
    void(Teacher ::*teacherSignal)(QString)=&Teacher::hungry;
    void(Student::*studentSlot)(QString)=&Student::treat;
    connect(th,teacherSignal,st,studentSlot);
//    classIsOver();

     //点击一个下课按钮,触发下课
    QPushButton * btn=new QPushButton("下课",this);
    //重置窗口大小
    this->resize(600,400);
    //点击按钮,触发下课
//    connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);


    void(Teacher ::*teacherSignal2)(void)=&Teacher::hungry;
    void(Student::*studentSlot2)(void)=&Student::treat;
    connect(th,teacherSignal2,st,studentSlot2);
    //信号连接信号
    connect(btn,&QPushButton::clicked,th,teacherSignal2);

    //断开信号
    disconnect(th,teacherSignal2,st,studentSlot2);

    //扩展
    //1、信号是可以连接信号;
    //2、一个信号可以连接多个槽函数;
    //3、多个信号可以连接同一个槽函数;
    //4、信号和槽函数的参数,必须类型一一对应;
    //5、信号的参数个数可以多余槽函数的参数个数。

    //Qt4版本以前的信号和槽连接方式
    //利用Qt4信号和槽,连接无参版本
    connect(th,SIGNAL(hungry()),st,SLOT(treat()));
    //优点参数直观,缺点类型不做检测L
}

void Widget::classIsOver(){
    //下课函数,调用后,触发老师饿了的信号
    emit th->hungry();
    emit th->hungry("宫保鸡丁");
}
Widget::~Widget()
{
    delete ui;
}


1、信号是可以连接信号;
 2、一个信号可以连接多个槽函数;
 3、多个信号可以连接同一个槽函数;
4、信号和槽函数的参数,必须类型一一对应;
5、信号的参数个数可以多余槽函数的参数个数。

使用lamdba


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建一个老师对象
    this->th=new Teacher(this);
    //创建一个学生对象
    this->st=new Student(this);

    //老师饿了,学生请客的连接
//    connect(th,&Teacher::hungry,st,&Student::treat);
    //调用下课函数,触发信号
//    classIsOver();

    //连接带参数的信号和槽
    //指针->地址
    //函数指针->函数地址
    void(Teacher ::*teacherSignal)(QString)=&Teacher::hungry;
    void(Student::*studentSlot)(QString)=&Student::treat;
    connect(th,teacherSignal,st,studentSlot);
//    classIsOver();

     //点击一个下课按钮,触发下课
    QPushButton * btn=new QPushButton("下课",this);
    //重置窗口大小
    this->resize(600,400);
    //点击按钮,触发下课
//    connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);


    void(Teacher ::*teacherSignal2)(void)=&Teacher::hungry;
    void(Student::*studentSlot2)(void)=&Student::treat;
    connect(th,teacherSignal2,st,studentSlot2);
    //信号连接信号
    connect(btn,&QPushButton::clicked,th,teacherSignal2);

    //断开信号
    disconnect(th,teacherSignal2,st,studentSlot2);

    //扩展
    //1、信号是可以连接信号;
    //2、一个信号可以连接多个槽函数;
    //3、多个信号可以连接同一个槽函数;
    //4、信号和槽函数的参数,必须类型一一对应;
    //5、信号的参数个数可以多余槽函数的参数个数。

    //Qt4版本以前的信号和槽连接方式
    //利用Qt4信号和槽,连接无参版本
    connect(th,SIGNAL(hungry()),st,SLOT(treat()));
    //优点参数直观,缺点类型不做检测

    //lambda
    //值传递
    [=](){
        btn->setText("AAA");
    }();
    //引用传递
    [&](){
        btn->setText("BBB");
    }();

    int ret=[]()->int{return 1000;}();
    qDebug()<<"ret="<<ret;

    //利用lambda表达式,实现点击按钮,关闭窗口
    QPushButton *btn2=new QPushButton;
    btn2->setText("关闭");
    btn2->move(100,0);
    btn2->setParent(this);
    connect(btn2,&QPushButton::clicked,this,[=](){
        emit th->hungry("lalala");
    });
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值