Qt应用程序开发框架
QT内置了大量信号和槽,还支持用户自定义信号 和 槽
一、自定义槽
- 有声明且有实现
- 返回值类型为void
- 槽函数 可以带参数,也可以重载(槽函数实参是从信号而来)
二、自定义信号
- 写在Signal:下方
- 只需声明,无需实现
- 返回值为void
- 支持带参,且可重载
- emit 可触发信号
三、自定义信号和槽的特点
- 一个信号可以被多个槽绑定
- 同一个槽函数,可以绑定多个信号
- 信号 和 槽的函数参数,需要一一对应
- 信号的参数列表,可以多于槽函数的参数列表; 反之,槽函数的参数列表不能多于信号的参数列表
- 信号可以绑定信号
四、信号和槽断开连接
disconnect 断开连接
connect 连接
五、代码实现
(1)新建Boss类 Boss.h 定义构造函数,添加变量,自定义信号及槽函数
#ifndef BOSS_H
#define BOSS_H
#include <QWidget>
class Boss : public QWidget
{
Q_OBJECT
public:
//explicit 关键字,修饰函数,参数,无法自动转换类型
explicit Boss(QString _name, int _exp, QWidget *parent = nullptr);
int exp;//经验值
QString name;//名字
//信号定义,下方添加的为自定义信号
signals:
//自定义信号
void DeadSignal();//定义阵亡信号
void DeadSignal(int _exp);//定义带参数的阵亡信号,重载
public slots://槽函数定义
void BossDeadSlot();//Boss 阵亡槽函数
};
#endif // BOSS_H
Boss.cpp 实现构造函数及槽函数
#include "Boss.h"
#include <QDebug>
Boss::Boss(QString _name, int _exp, QWidget *parent) : QWidget(parent)
{
exp = _exp;
name = _name;
}
void Boss::BossDeadSlot()
{
qDebug() << name << "被击杀! 掉落经验:" << exp;
}
(2)新建Role类 Role.h 定义槽函数
#ifndef ROLE_H
#define ROLE_H
#include <QWidget>
class Role : public QWidget
{
Q_OBJECT
public:
explicit Role(QWidget *parent = nullptr);
signals:
public slots:
void GetExp();//获得经验槽函数
void GetExp(int _exp);//具体获得经验函数,重载
};
#endif // ROLE_H
Role.cpp 实现槽函数,并重载函数,实现无参及有参的函数
#include "Role.h"
#include <QDebug>
Role::Role(QWidget *parent) : QWidget(parent)
{
}
void Role::GetExp()
{
qDebug() << "角色获得经验!";
}
void Role::GetExp(int _exp)
{
qDebug() << "角色获得" << _exp << "点经验!";
}
(3)widget.h 引入 Boss.h 及 Role.h 头文件,定义对象,并定义槽函数
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "Boss.h"
#include "Role.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Boss* mBoss;//BOSS 被观察者
Role* mRole;//角色 观察者
public slots:
//广播boss阵亡信号
void BossDeadBroadcast();
};
#endif // WIDGET_H
widget.cpp 信号和槽自定义的使用
#include "widget.h"
#include "Boss.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//观察者 boss,处理函数:dead打印
//被观察者 按钮,信号:点击
//按钮点击,处理boss阵亡
auto btn = new QPushButton("击杀", this);//被观察者 (信号源)
auto boss1 = new Boss("白蛇", 2000);//观察者
auto boss2 = new Boss("青蛇", 1500);//观察者
//绑定信号
connect(btn, &QPushButton::clicked, boss1, &Boss::BossDeadSlot);//必须加作用域,调用函数
//connect(btn, &QPushButton::clicked, this, &QWidget::showMaximized);//窗口放大
//boss 阵亡信号广播后,触发boss阵亡槽函数
//思路:点击按钮,触发阵亡信号,阵亡信号对应boss的阵亡处理槽函数
mBoss = new Boss("美猴王", 10000);
QPushButton* btn2 = new QPushButton("播放阵亡信号", this);
btn2->move(200, 0);
//点击按钮触发,信号广播,广播boss阵亡信号
connect(btn2, &QPushButton::clicked, this, &Widget::BossDeadBroadcast);
//阵亡信号触发,阵亡槽信号处理打印
//重载后无参 信号 和 槽 绑定
void(Boss::*DeadSignal0)() = &Boss::DeadSignal;
void(Boss::*BossDeadSlot0)() = &Boss::BossDeadSlot;
connect(mBoss, DeadSignal0, mBoss, BossDeadSlot0);
//boss阵亡信号触发后,角色获得经验处理
mRole = new Role;
//connect(mBoss, &Boss::DeadSignal, mRole, &Role::GetExp);
//重载连接带参的信号和槽
void(Boss::*deadSignal)(int) = &Boss::DeadSignal;//指针前添加作用域Boss 信号指针
void(Role::*getExp)(int) = &Role::GetExp;//带槽函数的槽指针
void(Role::*getExp0)() = &Role::GetExp;//无参槽函数指针
connect(mBoss, deadSignal, mRole, getExp0);
//信号 绑定 信号
auto btn3 = new QPushButton("信号连接信号测试", this);
btn3->move(0, 500);
//点击信号,绑定死亡信号
connect(btn3, &QPushButton::clicked, mBoss, DeadSignal0);
//断开信号 和 槽 连接
disconnect(btn3, &QPushButton::clicked, mBoss, DeadSignal0);
}
Widget::~Widget()
{
}
void Widget::BossDeadBroadcast()
{
//触发阵亡信号逻辑
qDebug() << "阵亡信号广播!";
emit mBoss->DeadSignal();//此处为触发信号 emit用于触发信号
emit mBoss->DeadSignal(mBoss->exp);//触发带参信号
}