qt 信号和槽的简明使用

发布时间:2023年12月21日

目录

1. connect函数?

2. 自定义的信号和槽

3. 带参数的信号和槽


1. connect函数?

connect(btn, &QPushButton::clicked, this, &Widget::close);

四个参数:

  • 参数1:信号发送者
  • 参数2:发送的信号signals(函数地址)
  • 参数3:信号接收者
  • 参数4:处理的slot槽函数(函数指针)
Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 用于初始化Widget类的基类,即QWidget。
{
    // 创建一个按钮
    QPushButton *btn = new QPushButton;
    btn->setParent(this);
    btn->setText(QString::fromLocal8Bit("按钮1"));

    // connect(信号发送者,发送的具体信号,信号接收者,信号的处理)
    connect(btn, &QPushButton::clicked, this, &QWidget::close);  // 点击按钮,关闭Widget
}

2. 自定义的信号和槽

信号:

  • 自定义信号,写在signals下。
  • 返回值是void,只需要声明,不需要实现
  • 可以有参数,所以可以重载

槽:

  • slots. 早期qt必须写在public slots下.
  • 返回值void,需要声明和实现
  • 可以有参数,所以可以重载

举个例子:下课了,触发老师发送饿了的信号,学生接受信号并进行请客吃饭事件。

程序:调用classIsOver(),触发老师hungry(), 学生接受信号并treat();

Teacher类

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
    void hungry();  // 信号
};

#endif // TEACHER_H
#include "teacher.h"

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

Student类

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);
    void treat();  // 槽函数

signals:
};

#endif // STUDENT_H

触发函数,即下课了。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#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;

    Teacher *t;
    Student *s;

    void classIsOver();  // 触发函数
};
#endif // WIDGET_H
#include "widget.h"
// #include "ui_widget.h"

// 下课后,老师饿了,学生请客吃饭。
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 信号发送者
    this->t = new Teacher();
    // 信号接收者
    this->s = new Student();

    // 绑定老师饿了,学生就请客吃饭
    connect(t, &Teacher::hungry, s, &Student::treat);

    // 调用触发函数
    classIsOver();
}

Widget::~Widget()
{
}

// 触发函数
void Widget::classIsOver()
{
    // 下课了,调用此触发函数classIsOver,触发老师饿了信号
    emit t->hungry();
}

3. 带参数的信号和槽

预备知识点

(1)普通函数指针:

int (*fp)(int a); // 这里就定义了一个指向函数(这个函数参数仅仅为一个 int 类型,函数返回值是 int 类型)的指针 fp。

(2)类函数指针:

int (Teacher:: *fp)(int a);? // 指向的是Teacher类中函数,该函数参数是int类型,返回值是int,指针变量是fp;

void (Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry;? // 指向的Teacher类中的hungry函数,该函数参数是QString类型,返回void类型。

同样用上面的吃饭例子:

下课了,触发老师饿了,老师吃烧鸡,学生接收吃烧鸡信号并请客。

// 触发函数
void Widget::classIsOver()
{
    // 下课了,调用此触发函数,触发老师饿了信号
    // emit t->hungry();
    emit t->hungry("烧鸡");  // Teacher *t;
}

Teacher类型,加一个带参声明。

#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类加一个带参函数

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

    // slots. 早期qt必须写在public slots下.
    // 返回值void,需要声明和实现
    // 可以有参数,所以可以重载
    void treat();
    void treat(QString foodName);
signals:
};

#endif // STUDENT_H
#include "student.h"
#include <QDebug>

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

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

void Student::treat(QString foodName)
{
    qDebug() << "eat: " << foodName;  // eat:  "烧鸡"
    qDebug() << "eat: " << foodName.toUtf8().data();  // eat:  烧鸡
}

定义函数指针,关联信号和槽

// 绑定老师饿了,学生就请客吃饭
// connect(t, &Teacher::hungry, s, &Student::treat);  // 不带参

void (Teacher:: *teacherSignal)(QString foodName) = &Teacher::hungry;
void (Student:: *studentSlot)(QString foodName) = &Student::treat;
connect(t, teacherSignal, s, studentSlot);  // 不带参

// 调用触发函数
classIsOver();

文章来源:https://blog.csdn.net/jizhidexiaoming/article/details/135112949
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。