【QT开发笔记-基础篇】| 第一章 QT入门 | 1.6 自定义信号槽
本节对应的视频讲解:B_站_链_接
https://www.bilibili.com/video/BV1gA4y1d7gz
上节课,我们讲解了标准信号槽,标准信号槽中,信号和槽函数,都是 Qt 框架定义好的。
Qt
还允许我们自定义信号和槽。
自定义信号和槽的条件:
- 自定义的类,要继承自
QObject
- 自定义的类,其中要声明一个宏
Q_OBJECT
只有满足了这两个条件才可以正常使用信号槽机制(当然,槽函数是全局函数、 Lambda
表达式等无需接收者的时候除外,后边讲解)。
1. 自定义信号槽案例
接下来,我们通过一个案例,演示自定义信号槽的使用。
案例:“长官” (Commander
)发送一个 “冲” (go
) 的信号,然后 “士兵" (Soldier
)执行“ 战斗” (fight
) 的槽函数
1.1 创建 Commander 类
在左侧项目文件名上右键 -> 添加新文件:
指定类名和父类
点击完成,即可添加cpp和.h文件到项目中
创建完成之后的 commander.cpp
和 commander.h 文件
,内容如下:
// commander.h
#ifndef COMMANDER_H
#define COMMANDER_H#include <QObject>// 1.自定义的类,需要继承自 QObject 类
class Commander : public QObject
{// 2.并且添加 Q_OBJECT 宏,才能正常使用 Qt 的信号和槽机制Q_OBJECT
public:explicit Commander(QObject *parent = nullptr);
// 3.在 signals 后面添加自定义的信号即可
signals:};#endif // COMMANDER_H// commander.cpp
#include "commander.h"Commander::Commander(QObject *parent): QObject{parent}
{}
1.2 添加自定义信号
在 signals
下面添加自定义的信号即可
class Commander : public QObject
{Q_OBJECT
public:explicit Commander(QObject *parent = nullptr);signals:// 1.信号只需声明,无需实现// 2.信号返回值为 voidvoid go();
};
1.3 添加 Soldier 类
按照同样的方法,添加 Soldier
类,创建完成之后的 soldier.h
和 soldier.cpp
文件,内容如下:
// soldier.h
#ifndef SOLDIER_H
#define SOLDIER_H#include <QObject>class Soldier : public QObject
{Q_OBJECT
public:explicit Soldier(QObject *parent = nullptr);signals:};#endif // SOLDIER_H// soldier.cpp
#include "soldier.h"Soldier::Soldier(QObject *parent): QObject{parent}
{}
1.4 添加自定义槽
Soldier
士兵类,需要实现一个 fight
的槽函数
class Soldier : public QObject
{Q_OBJECT
public:explicit Soldier(QObject *parent = nullptr);signals:// 1.通常将槽函数添加到 slots 后面
// 这个 slots 也可以不写。不过建议写上,以指明这是一个槽函数
// pulic,表示槽函数既可以在当前类及其子类的成员函数中调用,也可以在类外部的其它函数(比如 main() 函数)中调用
public slots:// 2.槽函数的返回值和参数,要和信号保持一致// 由于信号无返回值,因此槽函数也无返回值// 由于信号无参数,因此槽函数也无参数void fight();
};
在 soldier.h
文件中有了槽函数的声明,还需要在 soldier.cpp
中实现
可以在槽函数声明处,直接按 alt + enter
快捷键,快速生成函数定义
void Soldier::fight()
{qDebug() << "fight";
}
1.5 连接自定义的信号和槽
信号和槽都已经定义完毕, 接下来就可以进行连接了
在 mainwindow.cpp
中,定义 Commander
和 Soldier
类的实例,并建立信号和槽的连接,如下:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 1. 创建两个类的实例Commander commander;Soldier soldier;// 2. 建立信号和槽的连接connect(&commander, SIGNAL(go()), &soldier, SLOT(fight()));// 3. 发送信号// emit 可省略/*emit*/commander.go();
}
这样,在程序执行后,就可以在【应用程序输出】窗口看到槽函数执行的结果了:
1.6 信号和槽的重载
我们知道,信号和槽的本质就是函数,是函数就可以重载,因此,我们可以重载同名的信号,和重载同名的槽函数。
仍然以 Commander
和 Soldier
为例:
在 commander.h
中添加重载的 go
信号:
class Commander : public QObject
{Q_OBJECT
public:explicit Commander(QObject *parent = nullptr);signals:void go();void go(QString);
};
在 soldier.h
中添加重载的fight
槽函数:
class Soldier : public QObject
{Q_OBJECT
public:explicit Soldier(QObject *parent = nullptr);signals:public slots:void fight();void fight(QString);
};
在 soldier.cpp
中实现重载的fight
槽函数:
void Soldier::fight(QString s)
{qDebug() << "fight for" << s;
}
接下来在mainwindow.cpp
中同时发送重载的两个go
信号:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 1. 创建两个类的实例Commander commander;Soldier soldier;// 2. 建立信号和槽的连接connect(&commander, SIGNAL(go()), &soldier, SLOT(fight()));connect(&commander, SIGNAL(go(QString)), &soldier, SLOT(fight(QString)));// 3. 发送信号commander.go();commander.go("freedom");
}
此时执行程序,就可以在【应用程序输出】窗口看到两个重载的槽函数执行的结果了:
2. 信号槽总结
2.1 使用信号和槽的条件
如果要使用信号和槽,需要满足如下两个条件
- 自定义的类,要继承自
QObject
- 自定义的类,其中要声明一个宏
Q_OBJECT
只有满足了这两个条件才可以正常使用信号槽机制。
2.2 信号
- 无需实现
信号的本质是函数,并且只需要声明,不需要实现; - 可以重载
信号本质是函数,因此可以重载; - 信号声明在类头文件的
signals
域下; - 信号返回值类型为
void
,参数的类型和个数不限; - 信号可以使用
emit
关键字发射,emit
也可以省略;
2.3 槽
- 需要实现
槽的本质是函数,需要实现; - 可以重载
槽本质是函数,因此可以重载; - 槽函数用
slots
关键字修饰(其实在Qt5
中可以省略slots
关键字,下一节会讲解); - 返回值
槽函数的返回值,要和信号保持一致。由于信号的返回值为void
,因此槽函数的返回值也是void
- 参数
槽函数的参数个数要<=
信号的参数个数
也就是说:可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少),但是不能说信号根本没有这个数据,你就要在槽函数中使用(就是槽函数的参数比信号的多,这是不允许的)
本节对应的视频讲解:B_站_链_接
https://www.bilibili.com/video/BV1gA4y1d7gz
【QT开发笔记-基础篇】| 第一章 QT入门 | 1.6 自定义信号槽相关推荐
- 【QT开发笔记-基础篇】| 第二章 常用控件 | 2.12 表格控件 QTableWidget
本节对应的视频讲解:B_站_链_接 QTableWidget 是 Qt 中的表格控件,可以行列的形式来展示数据 1. 属性和方法 QTableWidget 有很多属性和方法,完整的可查看帮助文档. 在 ...
- 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.1 为什么要学习Qt
本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1334y1776z Qt 是一个跨平台的 C++ 图形用户界面应用程序框架 Qt 为应用程序开发 ...
- 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.2 搭建Qt开发环境
本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1Pr4y1x7fh Qt 开发主要有两种开发环境 Qt Creator 它是 Qt 官方提供的开 ...
- 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.4 项目构建流程
本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1cW4y1y7Lw 在上一节课中,我们新建了第一个 Qt 工程,其中包括 5 个文件: Hell ...
- 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.7 如何连接信号槽
本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1mN4y137H6 信号和槽要建立连接,本质上是通过 `connect` 函数来连接实现的. 但 ...
- 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.5 标准信号槽
本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1vW4y1676Q 本节讲解信号和槽的概念,以及标准的信号槽 1. 什么是信号槽 1.1 信号 ...
- 【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.1 效果演示、技术点
本节对应的视频讲解:B_站_视_频 https://www.bilibili.com/video/BV14P4y197pi Qt 中绘图用到的类是 QPainter,可以实现点.线.矩形.圆形.多边形 ...
- 【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.5 多段线、多边形
本节对应的视频讲解:B_站_视_频 https://www.bilibili.com/video/BV1ZP4y1S7Ax 本节讲解如何绘制多段线.多边形 1. 相关的 API 直接查看官方的帮助文档 ...
- 【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.12 文本、图片
本节对应的视频讲解:B_站_视_频 https://www.bilibili.com/video/BV1k14y1A7XL 本节讲解如何绘制文本 1. 相关的 API 直接查看官方的帮助文档,可以看到 ...
最新文章
- 2017年如何在移动端优雅的使用flex
- 自定义取值距离的javascript random()函数
- thinkPHP增删改查的方法案例
- android studio 集成 第三方sdk,Android FrameWork集成第三方SDK的jar包和so庫
- 40 SD配置-销售凭证设置-分配计划行类别
- python课设答辩问题及答案_HTML5网站前端开发设计答辩问题及答案
- Oracle体系概要
- DeFi 协议 Benchmark Protocol 启动第二阶段流动性挖矿计划 The Press
- 线性回归-最小二乘python实现
- 电信、联通合建 5G,将会碰出怎样的火花?
- Moment.js 一款JS时间封装库
- java计算器流程图_我的第一个JAVA程序之计算器
- nb模块不能接收公网消息_NB-IoT 对接调测问题汇总,你想知道的都在这儿 | 收藏吧...
- 办公自动化:PDF文件合并器,将多个PDF文件进行合并...
- 业务安全情报第四期:新能源车企重金打造的私域流量,成为黑灰产“掘金发财”的新目标
- JVM-什么是GC?
- 拼写检查工具是android,Android拼写检查器
- linux查看进程limits解释,linux中/etc/security/limits.conf配置文件说明
- 笔记记录软件:NoteRecorder
- mathtype 7.4安装教程
热门文章
- UpdateData(TRUE)与UpdateData(FALSE)用法
- Google Map开发系列(六)——谷歌地图坐标定位
- 求任意一个正整数的二进制中有多少个比特位为1
- 浙江大学计算机科学与技术学院导师,浙江大学计算机科学与技术专业导师介绍:徐从富...
- 华为与小米赛跑-续!!华为四款新机上市
- Flask操作指南,留着练习
- STM32F103系列(三):初识STM32F103
- 如何确认某日是否为工作日(休息日)
- AIDA64压力测试教程,AIDA64压力测试多长时间,AIDA64压力测试结果怎么看
- 谷粒学院(二十四)Jenkins+Maven+Github+Springboot实现可持续自动部署(非常详细)