目录
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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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();