信号和槽
概述
示例代码
// 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;
}