• QT基础入门——信号和槽机制(二)


    前言:

    在Qt中,有一种回调技术的替代方法:那就是信号和槽机制。当特定事件发生时,会发出一个信号。Qt的小部件中有许多预定义的信号,但我们可以将小部件子类化,向它们添加自定义的信号。槽是响应特定信号的函数

    目录

    一、QPushButton Class的创建

     二、对象树

    1.创建: 

    2. mypushbutton.h

    3. mypushbutton.cpp

    4.mywidget.cpp

    5.运行结果 

    三、QT坐标系 

    *四.信号和槽

    1.点击按钮关闭窗口

    2.自定义信号和槽

    (1)自定义信号

    (2)自定义槽函数

    (3)当定义信号和槽出现重载

    (4)信号连接信号

    (5)断开信号  

     3.代码实现

    (1)student.h

    (2)teacher.h

    (3)widget.h

    (4)student.cpp

    (5)teacher.cpp

    (6)widget.cpp

    4.Lambda表达式 

    5.整体框架 


    一、QPushButton Class的创建

    按钮控件头文件:#include

    1. #include "mywidget.h"
    2. #include
    3. myWidget::myWidget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. //创建一个按钮
    7. QPushButton * btn = new QPushButton;
    8. //btn->show();//show以顶层方式弹出窗口控件
    9. //让btn对象 依赖在myWidget窗口中
    10. btn->setParent(this);
    11. //显示文本
    12. btn->setText("第一个按钮");
    13. }
    14. myWidget::~myWidget()
    15. {
    16. }

    1. #include "mywidget.h"
    2. #include
    3. myWidget::myWidget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. //创建第二个按钮,按照控件大小创建窗口
    7. QPushButton * btn2 = new QPushButton("第二个按钮",this);
    8. //移动btn2按钮
    9. btn2->move(100,100);
    10. //重置窗口大小
    11. resize(600,400);
    12. //设置固定窗口大小
    13. setFixedSize(600,400);
    14. //设置窗口标题
    15. setWindowTitle("窗口");
    16. }
    17. myWidget::~myWidget()
    18. {
    19. }

     二、对象树

    当创建的对象在堆区时候,如果指定的父亲是object派生下来的类或者.QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。一定程度上简化了内存回收机制
     

    1.创建: 

     

     

    2. mypushbutton.h

    1. #ifndef MYPUSHBUTTON_H
    2. #define MYPUSHBUTTON_H
    3. #include
    4. class MyPushButton : public QPushButton
    5. {
    6. Q_OBJECT
    7. public:
    8. explicit MyPushButton(QWidget *parent = nullptr);
    9. ~MyPushButton();
    10. signals:
    11. };
    12. #endif // MYPUSHBUTTON_H

    3. mypushbutton.cpp

    1. #include "mypushbutton.h"
    2. #include
    3. MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
    4. {
    5. qDebug() << "我的按钮类构造调用";
    6. }
    7. MyPushButton ::~MyPushButton()
    8. {
    9. qDebug() << "我的按钮类析构";
    10. }

    4.mywidget.cpp

    1. #include "mywidget.h"
    2. #include
    3. #include
    4. #include
    5. myWidget::myWidget(QWidget *parent)
    6. : QWidget(parent)
    7. {
    8. //创建一个自己按钮的对象
    9. MyPushButton * myBtn = new MyPushButton;
    10. myBtn->setText("我自己的按钮");
    11. myBtn->move(200,0);
    12. myBtn->setParent(this); //设置到对象树中
    13. }
    14. myWidget::~myWidget()
    15. {
    16. qDebug() << "myWidget的析构调用";
    17. }

    5.运行结果 

    三、QT坐标系 

    坐标系:

    以左上角为原点(0,0)X向右增加   Y向下增加

     其坐标相对于父窗口而言

    *四.信号和槽

    connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))

    信号槽的优点:

    松散耦合﹐信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起

    1.点击按钮关闭窗口

    参数1   信号的发送者  

    参数2   发送的信号(函数的地址)  

    参数3   信号的接受者    

    参数4   处理的槽函数(函数的地址)

    1. #include "mywidget.h"
    2. #include
    3. #include
    4. #include
    5. myWidget::myWidget(QWidget *parent)
    6. : QWidget(parent)
    7. {
    8. //创建一个自己按钮的对象
    9. MyPushButton * myBtn = new MyPushButton;
    10. myBtn->setText("我自己的按钮");
    11. myBtn->move(200,0);
    12. myBtn->setParent(this); //设置到对象树中
    13. //需求 点击我的按钮关闭窗口
    14. //参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接受者 参数4 处理的槽函数
    15. //connect(myBtn,&MyPushButton::clicked,this,&myWidget::close);
    16. connect(myBtn,&QPushButton::clicked,this,&QWidget::close);
    17. }
    18. myWidget::~myWidget()
    19. {
    20. qDebug() << "myWidget的析构调用";
    21. }

    2.自定义信号和槽

    (1)自定义信号

            写到signals下

            返回void

            需要声明,不需要实现

            可以有参数,可以重载

    (2)自定义槽函数

            返回void

            需要声明,也需要实现

            可以有参数,可以重载

            写到public slot下或者public或者全局函数。

    (3)当定义信号和槽出现重载

            需要利用函数指针明确指向函数地址

        void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;    
    
        void(Student:: *studentSlot)(QString) = &Student::treat;   
    
        connect(zt,teacherSignal,st,studentSlot);

            QsString ----》char *先转成OByteArray(.toUtf8())再转char *()

    (4)信号连接信号

        无参信号和槽的连接  
        void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;  
      
        void(Student:: *studentSlot2)(void) = &Student::treat;    
            
        connect(zt,teacherSignal2,st,studentSlot2);   
    
        信号连接信号    
        connect(btn,&QPushButton::clicked,zt,teacherSignal2);
    

    (5)断开信号  

     disconnect(zt,teacherSignal2,st,studentSlot2);

     3.代码实现

    (1)student.h

    1. #ifndef STUDENT_H
    2. #define STUDENT_H
    3. #include
    4. class Student : public QWidget
    5. {
    6. Q_OBJECT
    7. public:
    8. explicit Student(QWidget *parent = nullptr);
    9. signals:
    10. public slots:
    11. //早期qt版本 必须写到public slots,高版本可以写到public或者全局下
    12. //返回值 void,需要声明也需要实现
    13. //可以有参数,可以发生重载
    14. void treat();
    15. };
    16. #endif // STUDENT_H

    (2)teacher.h

    1. #ifndef TEACHER_H
    2. #define TEACHER_H
    3. #include
    4. class Teacher : public QObject
    5. {
    6. Q_OBJECT
    7. public:
    8. explicit Teacher(QObject *parent = nullptr);
    9. signals:
    10. //自定义信号 写到signals下
    11. //返回值是void,只需要声明,不需要实现
    12. //可以有参数,可以重载
    13. void hungry();
    14. };
    15. #endif // TEACHER_H

    (3)widget.h

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include
    5. #include
    6. QT_BEGIN_NAMESPACE
    7. namespace Ui { class Widget; }
    8. QT_END_NAMESPACE
    9. class Widget : public QWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. Widget(QWidget *parent = nullptr);
    14. ~Widget();
    15. private:
    16. Ui::Widget *ui;
    17. Teacher * zt;
    18. Student * st;
    19. void classIsOver();
    20. };
    21. #endif // WIDGET_H

    (4)student.cpp

    1. #include "student.h"
    2. #include
    3. Student::Student(QWidget *parent) : QWidget(parent)
    4. {
    5. }
    6. void Student::treat()
    7. {
    8. qDebug()<<"请老师吃饭";
    9. }
    10. void Student::treat(QString foodName)
    11. {
    12. //QsString ----》char *先转成OByteArray(.toUtf8())再转char *()
    13. qDebug()<<"请老师吃饭,老师要吃"<toUtf8().data();
    14. }

    (5)teacher.cpp

    1. #include "teacher.h"
    2. Teacher::Teacher(QObject *parent) : QObject(parent)
    3. {
    4. }

    (6)widget.cpp

    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. #include
    4. //Teacher 类 老师类
    5. //Student 类 学生类
    6. //场景:下课后老师触发一个信号,饿了,学生响应信号 请客吃饭
    7. Widget::Widget(QWidget *parent)
    8. : QWidget(parent)
    9. , ui(new Ui::Widget)
    10. {
    11. ui->setupUi(this);
    12. //创建一个老师对象
    13. this->zt = new Teacher(this);
    14. //创建一个学生对象
    15. this->st = new Student(this);
    16. // //老师饿了,学生请客的连接
    17. // connect(zt,&Teacher::hungry,st,&Student::treat);
    18. // //调用下课函数
    19. // classIsOver();
    20. //连接带参数的信号和槽
    21. //指针---》地址
    22. //函数指针----》函数地址
    23. void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
    24. void(Student:: *studentSlot)(QString) = &Student::treat;
    25. connect(zt,teacherSignal,st,studentSlot);
    26. //调用下课函数
    27. classIsOver();
    28. //点击一个 下课的按钮,再触发下课
    29. QPushButton * btn = new QPushButton("下课",this);
    30. //重置窗口大小
    31. this->resize(600,400);
    32. //点击按钮触发下课
    33. //connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);
    34. //无参信号和槽的连接
    35. void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
    36. void(Student:: *studentSlot2)(void) = &Student::treat;
    37. connect(zt,teacherSignal2,st,studentSlot2);
    38. //信号连接信号
    39. connect(btn,&QPushButton::clicked,zt,teacherSignal2);
    40. //断开信号
    41. //disconnect(zt,teacherSignal2,st,studentSlot2);
    42. }
    43. void Widget::classIsOver()
    44. {
    45. //下课函数调用后触发老师饿了的信号
    46. //emit zt->hungry();
    47. emit zt->hungry("鱼香肉丝");
    48. }
    49. Widget::~Widget()
    50. {
    51. delete ui;
    52. }

    4.Lambda表达式 

    C++11中的Lambda 表达式用于定义并创建匿名的函效对象,以简化编程工作。
    []  标识符   匿名函数

    =  值传递

    &  引用传递

    ()  参数     {}  实现体

    mutable   修饰  值传递变量,可以修改拷贝出的数据,改变不了本体

    返回值  []()  ->  int {}

    最常用   [=](){}

    1. //利用Lambda表达式,实现点击按钮关闭窗口
    2. QPushButton *btn2 = new QPushButton;
    3. btn2->setText("关闭");
    4. btn2->move(100,0);
    5. btn2->setParent(this);
    6. connect(btn2,&QPushButton::clicked,this,[=](){
    7. // this->close();
    8. // emit zt->hungry("鱼香肉丝");
    9. btn2->setText("AAAAA");
    10. });

    5.整体框架 

  • 相关阅读:
    SpringMvc+Spring+MyBatis+Maven+Ajax+Json注解开发 利用Maven的依赖导入不使用架包模式 (实操十二)
    哈夫曼压缩算法-Python实现
    C++ 多线程thread
    【TypeScript】类型兼容:如何判断一个类型是否可以赋值给其他类型?
    C++ QT QLocalSocket/QLocalServer基操
    一文带你秒懂 字节序(byte order),比特序(bit order),位域(bit field)
    对 React Hook的闭包陷阱的理解,有哪些解决方案?
    Java多线程:Thread类常用API
    vue3 + vite 性能优化 ( 从5s -> 0.5s )
    【软考】系统集成项目管理工程师(三)信息系统集成专业技术知识③
  • 原文地址:https://blog.csdn.net/m0_63168877/article/details/133387450