QT信号与槽——观察者模式——回调函数
QT信号与槽——观察者模式——回调函数
1、QT信号与槽机制
1.1信号本质
信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候 Qt 对应的窗口类会发出某个信号。比如:信号的本质是事件
按钮单击、双击 |
---|
窗口刷新 |
鼠标移动、鼠标按下、鼠标释放 |
键盘输入 |
在QT中信号的发出者是某个实例化的类对象,对象内部可以进行相关事件的检测。
1.2槽的本质
在 Qt 中槽函数是一类特殊的功能的函数,在编码过程中也可以作为类的普通成员函数来使用。之所以称之为槽函数是因为它们还有一个职责就是对 Qt 框架中产生的信号进行处理。
比如:和朋友一起玩游戏(csgo),朋友说:我要丢闪了,于是我背身一下防闪;
实例对象 | 角色 | 描述 |
---|---|---|
朋友 | 信号发出者 | 信号携带的信息: 我要丢闪了 |
我 | 信号接收者 | 处理朋友发射的信号: 背身 |
在Qt中槽函数的所有者也是某个类的实例对象。
1.3信号和槽关系
在 Qt 中信号和槽函数都是独立的个体,本身没有任何联系,但是由于某种特性需求我们可以将二者连接到一起,在 Qt 中我们需要使用 QOjbect类中的 connect 函数进二者的关联。
QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
/*参数:- sender: 发出信号的对象- signal: 属于sender对象, 信号是一个函数, 这个参数的类型是函数指针, 信号函数地址- receiver: 信号接收者- method: 属于receiver对象, 当检测到sender发出了signal信号, receiver对象调用method方法,信号发出之后的处理动作*/// 参数 signal 和 method 都是函数地址, 因此简化之后的 connect() 如下:框架自动调用
connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);
2、标准信号槽
QT自带的一些信号与槽函数
3、自定义信号槽
Qt 框架提供的信号槽在某些特定场景下是无法满足我们的项目需求的,因此我们还设计自己需要的的信号和槽,同样还是使用 connect () 对自定义的信号槽进行连接。
如果想要在QT类中自定义信号槽, 需要满足一些条件, 并且有些事项也需要注意:
注意 |
---|
要编写新的类并且让其继承Qt的某些标准类 |
这个新的子类必须从QObject类或者是QObject子类进行派生 |
在定义类的头文件中加入 Q_OBJECT 宏 不加无法使用QT的信号槽机制
|
// 在头文件派生类的时候,首先像下面那样引入Q_OBJECT宏:
class MyMainWindow : public QWidget
{Q_OBJECT......
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow>
/* 引入 QPushButton */
#include <QPushButton> class MainWindow : public QMainWindow
{ Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); signals: /* 声明一个信号,只需声明,无需定义 */ void pushButtonTextChanged(); }; #endif // MAINWINDOW_H
3.1自定义信号
信号是类的成员函数,返回值必须是 void 类型,信号的名字可以根据实际情况进行指定,参数可以随意指定, 信号也支持重载,信号需要使用 signals 关键字进行声明, 使用方法类似于public等关键字,信号函数只需要声明, 不需要定义(没有函数体实现),在程序中发射自定义信号: 发送信号的本质就是调用信号函数,习惯性在信号函数前加关键字: emit, 但是可以省略不写,emit只是显示的声明一下信号要被发射了, 没有特殊含义,底层 emit == #define emit
// 举例: 信号重载
// Qt中的类想要使用信号槽机制必须要从QObject类派生(直接或间接派生都可以)
class Test : public QObject
{Q_OBJECT
signals:void AA();// 参数的作用是数据传递, 谁调用信号函数谁就指定实参// 实参最终会被传递给槽函数void AA(int a);
};
3.2自定义槽
自定义槽注意事项 |
---|
返回值必须是 void 类型 |
槽也是函数, 因此也支持重载 |
槽函数需要指定多少个参数, 需要看连接的信号的参数个数 |
槽函数的参数是用来接收信号传递的数据的, 信号传递的数据就是信号的参数 信号函数: void AA(int a, double b); 槽函数: void AA(int a, double b); 槽函数的参数应该和对应的信号的参数个数,从左到右类型依次对应 信号的参数可以大于等于槽函数的参数个数 == 信号传递的数据被忽略了 信号函数: void AA(int a, double b); 槽函数: void AA(int a); |
Qt中槽函数的类型是多样的
Qt 中的槽函数可以是类的成员函数、全局函数、静态函数、Lambda表达式(匿名函数) |
槽函数可以使用关键字进行声明: slots (Qt5中slots可以省略不写)
public slots: |
// class A
class A : public QObject
{Q_OBJECT
public:explicit A(QObject *parent = nullptr);signals:void sig(); // 不能表达出想要吃什么void sig(QString msg); // 可以通过参数表达想要吃什么
};// class B
class B : public QObject
{Q_OBJECT
public:explicit B(QObject *parent = nullptr);public slots:// 槽函数void slo(); // 不能知道信号发出者要吃什么void slo(QString msg); // 可以知道信号发出者要吃什么
};
4、信号槽扩展
信号与槽可以多对一,也可以一对多
QT4连接方式
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
QT5及以上连接方式
connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);
用QT5的连接方式时要注意槽函数重载问题,使用函数指针,比如:
// 定义函数指针指向重载的某一个具体的信号地址
void (Me::*mysignal)(QString) = &Me::eat;
// 定义函数指针指向重载的某一个具体的槽函数地址
void (Me::*myslot)(QString) = &Me::hungury;
// 使用定义的函数指针完成信号槽的连接
connect(&m, mysignal, &m, myslot);
最好使用QT5的连接方式,因为这样能检查出错误,QT4的使用宏定义把函数名变为字符串,即使写错了也不会报错;
参考:Qt开发编程-入门基础教程Qt5
【正点原子】 I.MX6U 嵌入式 Qt 开发指南 V1.0
QT信号与槽——观察者模式——回调函数相关推荐
- Qt信号和槽函数连接不成功原因
Qt信号和槽连接失败原因主要有以下几点: 1.槽函数并没有声明在类的public slots(或private slots或protected slots)里,因此,所想要成为槽函数的那个函数只是普普 ...
- 【Qt】Qt信号与槽使用不当,使程序崩溃
问题描述 跨线程使用Qt信号和槽,信号发送时间间隔小于槽函数处理时间时,造成程序崩溃. 原因分析 跨线程使用Qt信号和槽时,connect默认是QueuedConnection,队列连接方式. 信号传 ...
- QT 信号与槽 最简单例子
QT 信号与槽 最简单例子 main.cpp 和 my_head.h源码: [cpp] view plaincopy #ifndef MY_HEAD_H #define MY_HEAD_H #inc ...
- QT信号与槽(自定义带参数的信号)
关于QT信号与槽的问题其实每个初学QT的人都会遇到,当时我需要做一个带界面的demo,在信号和槽的问题上,我需要的想法是让槽可以有参数的进行操作,但是系统内置的clicked()信号是不含参数的,这对 ...
- Qt 信号和槽 事件处理
一:Qt信号和槽概述 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本章介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注意的一些问题. 信号和槽机制是QT的核心机制,要精通QT ...
- qt信号与槽连接的书写规范
环境 : vs2015 + qt 5.9.9 Qt信号和槽连接失败原因主要有以下几点: 1.槽函数并没有声明在类的public slots(或private slots或protected slot ...
- Qt信号与槽的五种连接方式
qt信号与槽的五种连接方式: 1.默认连接:如果是在同一线程等价于直连,在不同线程等价于队列连接 2.直连:信号在哪,在哪个线程执行(最好只在同一线程中用) 3.队列连接: 槽在哪就在哪个线程执行 ( ...
- Qt信号与槽传递自定义数据类型——两种解决方法
Qt信号与槽传递自定义数据类型--两种解决方法 参考文章: (1)Qt信号与槽传递自定义数据类型--两种解决方法 (2)https://www.cnblogs.com/tid-think/p/9300 ...
- Qt信号与槽传递QList动态数组
Qt信号与槽传递QList动态数组 根据实验,测试程序见下: - QString的QList动态数组能够通过signal-slot机制进行传递: - 自定义结构的QList动态数组也能通过signal ...
最新文章
- 如何基于消息中间件实现分布式事务?万字长文给你答案!!
- 欧拉函数(Euler_Function)
- 30天自制操作系统 pdf_30天自制操作系统:第四天:系统界面绘制
- tensorflow中batch normalization的用法
- BugkuCTF-MISC题赛博朋克
- 几个交换问题的咨询?
- 闰年流程图——18网三杨捷
- Matplotlib笔记(莫烦Python)
- 【日常点滴013】python雪球网沪深港美股情爬取
- mysql phpmyadmin 安装_phpMyAdmin 安装
- 肿瘤外显子数据分析指南 复现
- linux下cat导出日志,Linux命令:cat
- iOS系统3DTouch全解析
- [反汇编练习] 160个CrackMe之024
- MarkDown的简介
- CocosCreator知识库amp;amp;lt;二amp;amp;gt;关于TiledMap的系统学习教程(阶段性更新)
- 如何才能使自己看懂英文文献
- python-CST MWS自动采样
- GluonCV跑代码经常碰到的问题
- 教你怎么制作高大上的三维热力图
热门文章
- Linux(10)用户和组管理命令
- 微生物组-宏基因组分析第9期(报名直播课免费参加线下2020.10本年最后一期)
- SPIEC-EASI的微生物网络构建示例
- 微生物相关网络构建教程:MENA, LSA, SparCC和CoNet
- 南方科技大学环境学院夏雨教授博士后一名(环境微生物方向)
- R语言绘图:28个实用程序包
- Microbiome:宏蛋白质组揭示健康人肠道菌群的功能,离真相更近了一步
- 形状相似的物品_废弃物品在体育课中的再利用
- pandas使用rename函数重命名dataframe中数据列的名称、从而创建一个包含重复列名称的dataframe数据集
- R语言ggplot2可视化:可视化水平堆叠条形图(horizontal stacked bar plot)并在条形图中的每个分组条形区域显示区域占整体的百分比数值标签