目录
connect(btn, &QPushButton::clicked, this, &Widget::close);
四个参数:
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
}
信号:
槽:
举个例子:下课了,触发老师发送饿了的信号,学生接受信号并进行请客吃饭事件。
程序:调用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();
}
预备知识点:
(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();