Qt笔记之 信号和槽

信号和槽

概述

示例代码

// mywidget.cpp
#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton *btn = new QPushButton;
    btn->setParent(this); // 设置父窗口
    btn->setText("点击按钮关闭窗口"); // 设置文本

    resize(600,400); // 重置窗口大小

    btn->move(100,100); // 移动按钮

    this->setWindowTitle("信号和槽"); // 改变窗口标题

    this->setFixedSize(600,400); // 固定窗口大小

    // 需求:点击按钮关闭窗口
    // 参数1:指针 参数2:信号(点击) 参数3:指针(本窗口) 参数4:槽函数(关闭窗口)
    connect(btn,&QPushButton::clicked,this,&MyWidget::close);
}

MyWidget::~MyWidget()
{
    delete btn;
    delete btn2;
}

自定义信号和槽

项目结构:

代码:

// student.h
#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,Qt5后,可以写在public,全局和lambda表达式
    // 返回值void
    // 可以有参数,可以重载
    // 有声明,必须有实现
    void treat();
};

#endif // STUDENT_H

// 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();

public slots:
};

#endif // TEACHER_H

// mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include "student.h"
#include "teacher.h"

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();

    Teacher *t;
    Student *s;

    // 下课函数
    void classIsOver();
};

#endif // MYWIDGET_H

// student.cpp
#include "student.h"
#include <QDebug>

Student::Student(QObject *parent) : QObject(parent)
{

}

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

// mywidget.cpp
#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    // 创建具体对象
    this->t = new Teacher(this);
    this->s = new Student(this);

    // 绑定信号和槽
    connect(t,&Teacher::hungry,s,&Student::treat);

    classIsOver(); // 下课
}

void MyWidget::classIsOver() {
    // 触发信号
    emit this->t->hungry();
}

MyWidget::~MyWidget()
{
    delete t;
    delete s;
}

效果:

重载

代码:

// teacher.h
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    void hungry();

    void hungry(QString foodName);

public slots:
};

#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);

signals:

public slots:
    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() << "请老师吃饭";
}

void Student::treat(QString foodName) {
    qDebug() << "请老师吃" << foodName.toUtf8().data(); // 调用toUtf8转为QBtyeArray,再调用data转为char *
}

// mywidget.cpp
#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    // 创建具体对象
    this->t = new Teacher(this);
    this->s = new Student(this);

    // 绑定信号和槽
    // connect(t,&Teacher::hungry,s,&Student::treat);

    // 建立有参数的自定义信号和槽
    // 函数指针 -> 函数地址
    void(Teacher::*teacherSignal)(QString) = &Teacher::hungry;
    void(Student::*studentSignal)(QString) = &Student::treat;

    connect(t,teacherSignal,s,studentSignal);

    classIsOver(); // 下课
}

void MyWidget::classIsOver() {
    // 触发信号
    emit this->t->hungry();
    emit this->t->hungry("臭豆腐");
}

MyWidget::~MyWidget()
{
    delete t;
    delete s;
}

效果:

拓展

#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    // 创建具体对象
    this->t = new Teacher(this);
    this->s = new Student(this);

    // 绑定信号和槽
    // 无参信号和槽函数
    void(Teacher::*teacherNoSignal)() = &Teacher::hungry;
    void(Student::*studentNoSignal)() = &Student::treat;

    connect(t,teacherNoSignal,s,studentNoSignal);

    // 建立有参数的自定义信号和槽
    // 函数指针 -> 函数地址
    void(Teacher::*teacherSignal)(QString) = &Teacher::hungry;
    void(Student::*studentSignal)(QString) = &Student::treat;

    connect(t,teacherSignal,s,studentSignal);

    // 点击按钮下课
    QPushButton *btn = new QPushButton;
    btn->setParent(this);
    btn->setText("下课!");

    // 信号连接信号
    connect(btn,&QPushButton::clicked,s,studentNoSignal);

    // 拓展
    // 1. 信号可以连接信号
    // 2. 信号和槽可以断开连接disconnect
    // 3. 多个信号可以连接同一个槽函数
    // 4. 一个信号可以连接多个槽函数
    // 5. 信号和槽的参数类型必须一一对应
    // 6. 信号参数的个数可以多于槽函数,反之不可以(很重要)
}

void MyWidget::classIsOver() {
    // 触发信号
    emit this->t->hungry();
    emit this->t->hungry("臭豆腐");
}

MyWidget::~MyWidget()
{
    delete t;
    delete s;
    delete btn;
}
posted @ 2020-12-18 22:48  小宇宙zjy  阅读(117)  评论(0编辑  收藏  举报