IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【QT】 05QT中的信号和槽 -> 正文阅读

[C++知识库]【QT】 05QT中的信号和槽

??代码资源:https://download.csdn.net/download/qq_36926037/85019623

5.1 系统信号&系统槽函数

5.1.1 系统信号&系统槽函数的定义

??以按钮(QPushButton)类为例,系统已经为该类定义了信号和槽函数
在这里插入图片描述

5.1.2 系统信号&系统槽函数的连接

??前提条件:创建了窗口,窗口内包含按钮
??需求:通过按钮关闭窗口
??实现:
????connet(信号发送者,信号(地址),信号接受者,槽函数(地址))
????信号格式: &信号发送者所属类::信号 ??其中信号为系统为信号所属类创建的系统信号
????槽函数格式: &信号接受者所属类别::信号接受者处理信号的槽函数??其中槽函数为系统为信号接收者所属类创建的系统信号

#include "mywidget.h"
//(1)引入按钮头文件
#include "QPushButton"
//引入自定义的按钮
#include <mypushbutton.h>
//引入打印头文件
#include <QDebug>
myWidget::myWidget(QWidget *parent)
    : QWidget(parent)

{
    //(2)创建第一个按钮:首先引入头文件
    QPushButton *btn=new QPushButton;
    //2.1 显示按钮
    //2.1.1方法:使用show以顶层的方式弹出窗口或控件(新开辟窗口进行显示)
    //btn->show();
    //2.1.2 方法:让窗口或控件依赖在父窗口中(mywidget窗口)
    btn->setParent(this);
    //2.2显示按钮上文本
    btn->setText("第一个按钮");
    //(3)创建第二个按钮:
    //这种方法创建,会按照控件的大小生成窗口,需要重置窗口大小
    QPushButton *btn2=new QPushButton("第二个按钮",this);
    //移动按钮
    btn2->move(100,100);
    //重置窗口大小
    resize(600,400);
    //设置窗口标题
    setWindowTitle("第一个窗口");
    //设置固定窗口大小
     setFixedSize(600,400);
    //设置按钮大小
     btn->resize(100,50);
     //(4)创建自定义按钮的对象
     MyPushButton *btn3=new MyPushButton;
     btn3->setText("自定义按钮");
     btn3->move(100,200);
     btn3->setParent(this);//设置到对象树中

     //(5)
     //需求点击我的按钮,关闭窗口
     //参数1:信号发送者(某个组件,如按钮)
     //参数2:发送的信号
     //     (利用系统的信号,可以查看帮助文档。比如信号发送者是按钮,系统为按钮类设计了相关的信号如点击,长按..)
     //参数3:信号接受者
     //参数4:(信号接受者)处理的槽函数
     //      (利用系统的槽函数,可以参看帮助文档。比如接受者是窗口,系统为窗口设计了相关的槽函数,如关闭,隐藏..)
     connect(btn3,&MyPushButton::clicked,this,&myWidget::close);
     connect(btn2,&QPushButton::clicked,this,&QWidget::close);
   
}
myWidget::~myWidget()
{
    //窗口类对象的析构函数
    qDebug()<<"窗口对象的析构"<<endl;
}

在这里插入图片描述

5.2 自定义信号&自定义槽函数

5.2.1 自定义信号&自定义槽函数的创建

??实现:
????connet(信号发送者,信号(地址),信号接受者,槽函数(地址))
????信号格式: &信号发送者所属类::信号 ??其中信号为自定义的信号
????槽函数格式: &信号接受者所属类别::信号接受者处理信号的槽函数??其中槽函数为自定义信号

??(1)创建一个新项目,并且新项目包含一个空窗口,效果如下图所示:
在这里插入图片描述
??(2)创建Teacher类和student类
在这里插入图片描述
在这里插入图片描述
??(3) 自定义信号:写在头文件中类的signals里面;信号返回值为void类型;信号只需要声明不需要实现;可以有参数,可以重载
在这里插入图片描述

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    //(1)自定义信号写在signals里面
    //(2)返回值为void类型
    //(3)只需要声明不需要实现:在cpp中不需要实现
    //(4)可以有参数,可以重载
    void hungry();
    
};

#endif // TEACHER_H

在这里插入图片描述

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

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

}

??(4)自定义槽函数:写在头文件的类的public slots里面或者写在public 或者全局下;返回值为void类型;需要声明也需要实现;可以有参数,可以重载
在这里插入图片描述

#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或者全局下
    //(1)返回值为void
    //(2)需要声明也需要实现
    //(3)可以有参数,可以发生重载
    void treat();

};

#endif // STUDENT_H

在这里插入图片描述

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

}
//槽函数实现
void Student::treat()
{
     qDebug()<<"请老师吃饭"<<endl;
}

5.2.2 自定义信号&自定义槽函数的连接

??(5)在窗口中, 使用槽函数和信号:首先创建信号发送者和信号接受者;然后通过connect建立连接;最后使用emit关键字触发信号,信号将通过连接传给信号接受者启动槽函数(头文件和源文件的相关代码)
在这里插入图片描述

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>

//(1)引入头文件
#include "teacher.h"
#include "student.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    
    //(2)声明对象
    Teacher * zt;
    Student * st;
    //(3)下课的函数
    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);
    
    //(1)创建老师对象和学生对象(这些对象都是窗口类的私有对象)
    //窗口对象里有一个zt对象
    this->zt=new Teacher(this);
    //窗口对象里有一个st对象
    this->st=new Student(this);
    
    //(2)老师饿了学生请客的——》链接
    connect(zt,&Teacher::hungry,st,&Student::treat);
    //参数1:信号发送者
    //参数2:信号
    //参数3:信号接受者
    //参数4:槽函数
    //(3)调用下课函数
    classIsOver();//调用classisover函数,该函数用于触发老师
        //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
        //接收,然后调用槽函数
}
void Widget ::classIsOver()
{
    //下课函数,调用后出发老师饿了的信号(自定义信号)
    //  触发信号的关键字emit
    emit zt->hungry();
}

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

5.3 重载的自定义信号&自定义槽函数

5.3.1 创建重载的自定义信号&自定义槽函数

??项目背景:基于5.2节项目
??(1)创建重载信号
在这里插入图片描述

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    //(1)自定义信号写在signals里面
    //(2)返回值为void类型
    //(3)只需要声明不需要实现:在cpp中不需要实现
    //(4)可以有参数,可以重载
    void hungry();
    
    //信号发生重载
    void hungry(QString foodName);


};

#endif // TEACHER_H

在这里插入图片描述

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

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或者全局下
    //(1)返回值为void
    //(2)需要声明也需要实现
    //(3)可以有参数,可以发生重载
    void treat();
    
    //槽函数发生重载
    void treat(QString foodName);

};

#endif // STUDENT_H

在这里插入图片描述

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

}
//槽函数实现
void Student::treat()
{
     qDebug()<<"请老师吃饭"<<endl;
}

//槽函数重载的实现
void Student::treat(QString foodName)
{
     qDebug()<<"请老师吃法,老师要吃"+foodName<<endl;
}

??(3)使用重载的槽函数和信号

5.3.2 连接重载的自定义信号&槽函数

5.3.2.1 有参信号连接有参槽函数

??3.1 使用有参的槽函数和信号:需要明确(重载)信号和(重载)槽函数的地址:例 void (Teacher::*teacherSignal )(QString)=&Teacher::hungry---------》代表参数为QString的重载函数的地址
??代码:connect(信号发送者,有参信号(地址),信号接受者,有参槽函数(地址))
在这里插入图片描述

#include "widget.h"
#include "ui_widget.h"

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

    //(1)创建老师对象和学生对象(这些对象都是窗口类的私有对象)
    //窗口对象里有一个zt对象
    this->zt=new Teacher(this);
    //窗口对象里有一个st对象
    this->st=new Student(this);

    //(2)老师饿了学生请客的——》链接
//    connect(zt,&Teacher::hungry,st,&Student::treat);
    //参数1:信号发送者
    //参数2:信号
    //参数3:信号接受者
    //参数4:槽函数

    //发生(信号,槽函数)重载时建立连接
    //函数指针指向函数地址,在建立连接的时候,指明信号和槽函数的函数地址,传入连接中
    void (Teacher::*teacherSignal )(QString)=&Teacher::hungry;//将有参的信号的地址付给teacherSignal
    void (Student ::*studentSlot )(QString)=&Student::treat;//将有参的槽函数付给studentSlot
    connect(zt,teacherSignal,st,studentSlot);


    //(3)调用下课函数
    classIsOver();//调用classisover函数,该函数用于触发老师
        //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
        //接收,然后调用槽函数
}
void Widget ::classIsOver()
{
    //下课函数,调用后出发老师饿了的信号(自定义信号)
    //  触发信号的关键字emit
//    emit zt->hungry();

    emit zt->hungry("宫爆鸡丁");
}

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

5.3.2.2 无参信号连接无参槽函数

??3.2 使用无参的槽函数和信号:需要明确(重载)信号和(重载)槽函数的地址:例 void (Teacher::*teacherSignal )(void)=&Teacher::hungry---------》代表无参的函数的地址
??代码:connect(信号发送者,无参信号(地址),信号接受者,无参槽函数(地址))
在这里插入图片描述

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

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

    //(1)创建老师对象和学生对象(这些对象都是窗口类的私有对象)
    //窗口对象里有一个zt对象
    this->zt=new Teacher(this);
    //窗口对象里有一个st对象
    this->st=new Student(this);

    //(2)老师饿了学生请客的——》链接
//    connect(zt,&Teacher::hungry,st,&Student::treat);
    //参数1:信号发送者
    //参数2:信号
    //参数3:信号接受者
    //参数4:槽函数

    //发生(信号,槽函数)重载时建立连接
    //2.1 有参的信号和槽函数建立连接
    //函数指针指向函数地址,在建立连接的时候,指明信号和槽函数的函数地址,传入连接中
    void (Teacher::*teacherSignal )(QString)=&Teacher::hungry;//将有参的信号的地址付给teacherSignal
    void (Student ::*studentSlot )(QString)=&Student::treat;//将有参的槽函数付给studentSlot
    connect(zt,teacherSignal,st,studentSlot);
    
    //2.2 无参的槽函数和信号建立连接
    void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
    void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
    connect(zt,teacherSignal1,st,studentSlot1);

    //(3)调用下课函数
    classIsOver();//调用classisover函数,该函数用于触发老师
        //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
        //接收,然后调用槽函数
}
void Widget ::classIsOver()
{
    //下课函数,调用后出发老师饿了的信号(自定义信号)
    //  触发信号的关键字emit
    emit zt->hungry();

//    emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
    delete ui;
}

5.4 信号&信号连接

5.4.1 信号连接信号

??代码:connect(信号发送者,信号(地址),信号接受者,信号(地址))
??流程:一个按钮点击信号——>触发第一个连接的信号——>该信号触发另一个连接的槽函数
在这里插入图片描述

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

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

    //(1)创建老师对象和学生对象(这些对象都是窗口类的私有对象)
    //窗口对象里有一个zt对象
    this->zt=new Teacher(this);
    //窗口对象里有一个st对象
    this->st=new Student(this);

    //(2)老师饿了学生请客的——》链接
//    connect(zt,&Teacher::hungry,st,&Student::treat);
    //参数1:信号发送者
    //参数2:信号
    //参数3:信号接受者
    //参数4:槽函数

    //发生(信号,槽函数)重载时建立连接
    //2.1 有参的信号和槽函数建立连接
    //函数指针指向函数地址,在建立连接的时候,指明信号和槽函数的函数地址,传入连接中
    void (Teacher::*teacherSignal )(QString)=&Teacher::hungry;//将有参的信号的地址付给teacherSignal
    void (Student ::*studentSlot )(QString)=&Student::treat;//将有参的槽函数付给studentSlot
    connect(zt,teacherSignal,st,studentSlot);

    //2.2 无参的槽函数和信号建立连接
    void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
    void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
    connect(zt,teacherSignal1,st,studentSlot1);

    //(3)调用下课函数
//    classIsOver();//调用classisover函数,该函数用于触发老师
        //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
        //接收,然后调用槽函数

    //(4)信号连接信号:
    QPushButton *btn1=new QPushButton;
    btn1->setParent(this);
    btn1->setText("下课");
//    connect(btn1,&QPushButton::clicked ,this,&Widget::classIsOver);
    //
    connect(btn1,&QPushButton::clicked,zt,teacherSignal1);


}
void Widget ::classIsOver()
{
    //下课函数,调用后出发老师饿了的信号(自定义信号)
    //  触发信号的关键字emit
    emit zt->hungry();

//    emit zt->hungry("宫爆鸡丁");
}

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

5.4.2 信号断开信号

??代码:disconnect(信号发送者,信号,信号接受者,信号)
在这里插入图片描述

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

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

    //(1)创建老师对象和学生对象(这些对象都是窗口类的私有对象)
    //窗口对象里有一个zt对象
    this->zt=new Teacher(this);
    //窗口对象里有一个st对象
    this->st=new Student(this);

    //(2)老师饿了学生请客的——》链接
//    connect(zt,&Teacher::hungry,st,&Student::treat);
    //参数1:信号发送者
    //参数2:信号
    //参数3:信号接受者
    //参数4:槽函数

    //发生(信号,槽函数)重载时建立连接
    //2.1 有参的信号和槽函数建立连接
    //函数指针指向函数地址,在建立连接的时候,指明信号和槽函数的函数地址,传入连接中
    void (Teacher::*teacherSignal )(QString)=&Teacher::hungry;//将有参的信号的地址付给teacherSignal
    void (Student ::*studentSlot )(QString)=&Student::treat;//将有参的槽函数付给studentSlot
    connect(zt,teacherSignal,st,studentSlot);

    //2.2 无参的槽函数和信号建立连接
    void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
    void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
    connect(zt,teacherSignal1,st,studentSlot1);

    //(3)调用下课函数
//    classIsOver();//调用classisover函数,该函数用于触发老师
        //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
        //接收,然后调用槽函数

    //(4)信号连接信号:
    QPushButton *btn1=new QPushButton;
    btn1->setParent(this);
    btn1->setText("下课");
//    connect(btn1,&QPushButton::clicked ,this,&Widget::classIsOver);
    //

   connect(btn1,&QPushButton::clicked,zt,teacherSignal1);

    //(5)信号断开信号
    disconnect(btn1,&QPushButton::clicked,zt,teacherSignal1);


}
void Widget ::classIsOver()
{
    //下课函数,调用后出发老师饿了的信号(自定义信号)
    //  触发信号的关键字emit
    emit zt->hungry();

//    emit zt->hungry("宫爆鸡丁");
}

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

5.5 信号和槽总结

??(1)一个信号可以连接多个槽函数
??(2)多个信号可以连接一个槽函数
??(3)信号和槽函数的参数必须类型一一对应
??(4)信号和槽函数的参数个数不需要一致,信号参数个数可以多余槽函数参数个数,并且槽函数的参数与信号的参数类型一致,反之不可以
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:20:07  更:2022-03-22 20:20:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:17:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码