Qt学习笔记3——信号和槽,自定义信号和槽,自定义信号和槽发生重载

  • P9. 信号和槽——点击按钮关闭窗口
  • P10. 自定义的信号和槽
  • P11. 自定义的信号和槽发生重载的解决
  • (P9. 信号和槽)

 

示例代码:

1 //需求:点击“我自己的窗口”,关闭窗口
2     //参数1.信号的发送者(这里是按钮);参数2.发送的信号(函数的地址);参数3.信号的接收者(这里是这个窗口);参数4.处理的槽函数(函数的地址)
3     //connect(mybtn,&MyPushButton::clicked,this,&Widget::close);
4     connect(mybtn,&QPushButton::clicked,this,&QWidget::close);  //上面一行代码与这行代码都能运行成功,区别就是函数的地址一个用的&MyPushButton,一个用的&QPushButton...

 

connect(信号的发送者,发送的信号,信号的接收者,处理的槽函数)

信号:signal  槽:slot

信号和槽 中的“槽”指的就是处理的“槽函数”。

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

  • (P10. 自定义的信号和槽)

(在已有的项目中添加新文件:

  在左侧右键项目名称(.pro文件上面的)-> Add New-> 新窗口中左侧选C++,中间选C++ Class,然后choose-> 修改Class name 和 Base class,下一步 -> 完成

自定义信号

  写到 signals 下  (此 signals 在相应的 头文件,相应的 类的定义 里)

  返回类型void

  只需要声明,不需要实现

  可以有参数,可以发生重载

自定义槽函数:

  写到 public slots 或者 public 或者 全局函数  (也是在相应的头文件中,相应的类的定义里)

  返回类型void

  需要声明,也需要实现

  可以有参数,可以重载

触发自定义的信号:emit 自定义信号;

案例:下课后,老师触发“饿了”信号,学生响应信号,请客吃饭

1. 在项目中分别Add New,自定义Teacher Class 和 Student Class

2. 在 teacher.h 中的 Teacher 类中的 signals 里声明“饿了”函数 hungry(); (相当于自定义信号,不需要写实现)

1 signals:
2     //自定义信号写到signals下
3     //规定:返回值是void,只需要声明,不需要实现
4     //可以有参数,可以重载
5     void hungry();

 

3. 在 student.h 中的Student 类中的 public slots 里声明“请客”函数 treat(); (相当于自定义槽函数,后续还需要写实现)

1 public slots:
2     //槽函数,早期Qt版本 必须写到public slots,高级版本可以写到public或者全局下
3     //返回值void,需要声明,也需要实现
4     //可以有参数,可以发生重载
5     void treat();

 

4. 在 student.cpp 里写 treat() 函数实现;(写槽函数定义)

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

 

注意:使用 qDebug() 时需要 #include <QDeBug>

5. 在 widget.h 中,包含“teacher.h” 和 “student.h”,并创建一个Teacher类、一个Student类和一个“下课”函数 ClassOver() 供之后使用;

#include "teacher.h"
#include "student.h"
...
...
private:
    Ui::Widget *ui;
    Teacher * zt;
    Student *st;
    void ClassOver();

 

6. widget.cpp 中实现

 1 Widget::Widget(QWidget *parent)
 2     : QWidget(parent)
 3     , ui(new Ui::Widget)
 4 {
 5     ui->setupUi(this);
 6 
 7     //创建一个老师对象
 8     this->zt = new Teacher(this); //this指定了父亲
 9     //创建一个学生对象
10     this->st = new Student(this);
11     connect(zt,&Teacher::hungry,st,&Student::treat);
12 
13     //调用下课函数
14     ClassOver();  //connect之后再调用ClassOver(),否则还没connect就调用ClassOver()将不会实现想要的功能
15 }
16 
17 void Widget::ClassOver()
18 {
19     //下课函数,调用后,触发老师饿了的信号
20     emit zt->hungry();
21 }
  • (P11. 自定义的信号和槽发生重载的解决)

当自定义信号和槽发生重载时,需要利用函数指针,明确指向函数的地址

  • 函数指针语法:

  函数返回值类型(* 指针变量名)(函数参数列表); 

  • QString 转 char * :先用 toUtf8() 转成QByteArray,在用 data() 转成 char *
  • 代码:

teacher.h

signals:
    void hungry();
    void hungry(QString foodname);

 

student.h

public slots:
    void treat();
    void treat(QString foodname);

 

student.cpp

void Student::treat(QString foodname)
{
    //QString 转成 char *(foodname是QString类型,打印的时候会被自动加双引号“”,不统一、不好看)
    //先转成QByteArray(用toUtf8()),再转成char *(用data())
    qDebug()<<"Invite the teacher to "<<foodname.toUtf8().data();
}

 

widget.cpp

 1     //连接带参数的信号和槽
 2     void(Teacher::*teachersig)(QString)=&Teacher::hungry;  //函数指针,Teacher::是作用域
 3     void(Student::*studentslot)(QString)=&Student::treat;  //函数指针
 4     connect(zt,teachersig,st,studentslot);
 5     ClassOver();
 6   ...
 7   ...
 8   void Widget::ClassOver()
 9   {
10       emit zt->hungry("烤鸭");
11   }

 (〃>_<;〃)(〃>_<;〃)(〃>_<;〃)

posted @ 2022-07-31 20:39  我会变强的  阅读(152)  评论(0编辑  收藏  举报