QT信号与槽机制

2023-11-13

QT开发——QT信号与槽机制

一、QT消息模型

QT封装了具体操作系统的消息机制,遵循经典的GUI消息驱动事件模型。

QT定义了与操作系统消息相关的自己的概念,即信号与槽。

信号signal是由操作系统产生的消息。

槽slot是程序中的消息处理函数。

connect将系统消息绑定到消息处理函数。

信号到槽的连接必须发生在两个QT对象间。

bool QObject::connect ( const QObject * sender, //发生对象

const char * signal, //消息名

const QObject * receiver, //接收对象

const char *method, //接收对象的成员函数

Qt::ConnectionType type = Qt::AutoConnection )

在QT中消息使用字符串进行描述,connect函数在消息名和处理函数之间建立映射。

QT中的关键字

SIGNAL用于指定消息名

SLOT用于指定消息处理函数名

Q_OBJECT所以自定义槽的类必须在类声明的开始处加上Q_OBJECT

slots用于在类中声明消息处理函数

二、信号与槽机制

信号和槽机制是QT的核心机制,是一种高级接口,应用于QT对象之间的通信,是QT的核心特性,也是QT区别于其它工具包的重要地方。信号和槽是QT自行定义的一种通信机制,独立于标准的C/C++语言,要正确的处理信号和槽,必须借助一个称为moc(Meta Object Compiler)的QT工具,MOC工具是一个C++预处理程序,为高层次的事件处理自动生成所需要的附加代码。

在QT中信号和槽取代了传统GUI框架中的回调函数,信号和槽能携带任意数量和任意类型的参数,是类型完全安全的。所有从QObject或其子类(如Qwidget)派生的类都能够包含信号和槽。当对象改变其状态时,信号就由对象发射(emit)出去,但对象不知道另一端是谁在接收信号。槽用于接收信号,但槽是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接,而且对象并不了解具体的通信机制。

1、信号

当某个信号对其客户或所有者发生的内部状态发生改变,信号被一个对象发射。只有定义过这个信号的类及其派生类能够发射这个信号。当一个信号被发射时,与其相关联的槽将被立刻执行,就象一个正常的函数调用一样。信号-槽机制完全独立于任何GUI事件循环。只有当所有的槽返回以后发射函数(emit)才返回。 如果存在多个槽与某个信号相关联,当这个信号被发射时,这些槽将会一个接一个地执行,但执行的顺序将会是随机的,不能人为地指定哪个先执行、哪个后执行。

信号的声明是在头文件中进行的,QT的signals关键字指出进入了信号声明区,随后即可声明自己的信号。

signals:

 void overflow();

signals是QT的关键字,而非C/C++的。信号可以重载,但信号却没有函数体定义,并且信号的返回类型都是void,不要指望能从信号返回什么有用信息。

信号由moc自动产生,不应该在.cpp文件中实现。

2、槽
槽是普通的C++成员函数,可以被正常调用,唯一的特殊性就是很多信号可以与其相关联。当与其关联的信号被发射时,信号关联的槽就会被调用。槽可以有参数,但槽的参数不能有缺省值。

槽是普通的成员函数,也有访问权限。槽的访问权限决定了谁能够与其相关联。同普通的C++成员函数一样,槽函数也分为三种类型,即public slots、private slots和protected slots。

public slots:使用publicslots声明的槽表示任何对象都可将信号与之相连接。在组件编程中,可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。

protected slots:使用protected slots声明的槽表示当前类及其子类可以将信号与之相连接。适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。

private slots:使用private slots声明的槽表示只有类自己可以将信号与之相连接,适用于联系非常紧密的类。

槽也能够声明为虚函数。

槽的声明也是在头文件中进行的。

public slots:

 void setValue(int value);

自定义槽

只有QObject的子类才能自定义槽

定义槽的类必须在类声明的最开始处使用Q_OBJECT

类中声明槽是需要使用slots关键字

槽与所处理的信号在函数签名上必须一致

SIGNAL与SLOT指定的名称中可以包含参数类型,不能包含具体的参数名

错误Object::connect:No such slot

A、检查类对象是否继承自QObject

B、检查类声明的开始处是否添加Q_OBJECT

C、检查是否使用slots对槽进行声明

D、检查槽的名称偏斜是否错误

E、重新编译工程

3、信号与槽的关联
通过调用QObject对象的connect函数来将某个对象的信号与另外一个对象的槽函数相关联,当发射者对象发射信号时,接收者对象的槽函数将被调用。connect函数的定义如下:

bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection )

connect函数的作用就是将发射者sender对象中的信号signal与接收者receiver中的method槽函数联系起来。当指定信号signal时必须使用QT的宏SIGNAL(),当指定槽函数时必须使用宏SLOT()。如果发射者与接收者属于同一个对象的话,那么在connect 调用中接收者参数可以省略。

一个信号能够与另一个信号相关联,此时发射者发出信号后接收者的信号也会接着发射。

当信号与槽没有必要继续保持关联时,可以使用disconnect函数来断开连接。

bool QObject::disconnect ( const QObject * sender, const char * signal, const QObject * receiver, const char *method )

disconnect函数断开发射者中的信号与接收者中的槽函数之间的关联。

在disconnect函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为0,其它三个参数的值可以等于0。

以下三种情况需要使用disconnect()函数断开信号与槽的关联:

A、断开与某个对象相关联的任何对象

disconnect(sender, 0, 0, 0);

    sender->disconnect();

B、断开与某个特定信号的任何关联

disconnect(sender, SIGNAL(mySignal()), 0, 0);

    sender->disconnect(SIGNAL(mySignal()));

C、断开两个对象之间的关联

disconnect(sender, 0, receiver, 0);

    sender->disconnect(receiver);

Qt利用信号与槽(signals/slots)机制取代传统的callback来进行对象之间的沟通。当操作事件发生的时候,对象会发提交一个信号(signal);而槽(slot)则是一个函数接受特定信号并且运行槽本身设置的动作。信号与槽之间,则通过QObject的静态方法connect来链接。

信号在任何运行点上皆可发射,甚至可以在槽里再发射另一个信号,信号与槽的链接不限定为一对一的链接,一个信号可以链接到多个槽或多个信号链接到同一个槽,甚至信号也可连接到信号。

以往的callback缺乏类型安全,在调用处理函数时,无法确定是传递正确型态的参数。但信号和其接受的槽之间传递的数据型态必须要相符合,否则编译器会提出警告。信号和槽可接受任何数量、任何型态的参数,所以信号与槽机制是完全类型安全。

信号与槽机制也确保了低耦合性,发送信号的类的并不知道是哪个槽会接受,也就是说一个信号可以调用所有可用的槽。此机制会确保当在"连接"信号和槽时,槽会接受信号的参数并且正确运行。

4、元对象工具
元对象编译器moc(meta object compiler)对C++文件中的类声明进行分析并产生用于初始化元对象的C++代码,元对象包含全部信号和槽的名字以及指向槽函数的指针。

moc读C++源文件,如果发现有Q_OBJECT宏声明的类,就会生成另外一个C++源文件,新生成的文件中包含有该类的元对象代码。例如,假设我们有一个头文件mysignal.h,在这个文件中包含有信号或槽的声明,那么在编译之前 moc 工具就会根据该文件自动生成一个名为mysignal.moc.h的C++源文件并将其提交给编译器;对应于mysignal.cpp文件moc工具将自动生成一个名为mysignal.moc.cpp文件提交给编译器。

元对象代码是signal/slot机制所必须的。用moc产生的C++源文件必须与类实现一起进行编译和连接,或者用#include语句将其包含到类的源文件中。moc并不扩展#include或者#define宏定义,只是简单的跳过所遇到的任何预处理指令。

信号和槽函数的声明一般位于头文件中,同时在类声明的开始位置必须加上Q_OBJECT语句,Q_OBJECT语句将告诉编译器在编译之前必须先应用moc工具进行扩展。关键字signals是对信号的声明,siganls没有public、private、protected等属性,slots是对槽函数的声明,slots有public、private、protected等属性。signals、slots关键字是QT 自己定义的,不是C++中的关键字。

信号的声明类似于函数的声明而非变量的声明,左边要有类型,右边要有括号,如果要向槽中传递参数的话,在括号中指定每个形式参数的类型,当然,形式参数的个数可以多于一个。

关键字slots指出随后开始槽的声明,这里slots用的也是复数形式。

槽的声明与普通函数的声明一样,可以携带零或多个形式参数。既然信号的声明类似于普通C++函数的声明,那么,信号也可采用C++中虚函数的形式进 行声明,即同名但参数不同。例如,第一次定义的void mySignal()没有带参数,而第二次定义的却带有参数,从这里我们可以看到QT的信号机制是非常灵活的。

信号与槽之间的联系必须事先用connect函数进行指定。如果要断开二者之间的联系,可以使用函数disconnect。

5、信号与槽机制的局限
信号与槽是一种高效灵活的通信机制,但有其缺陷:

A、信号与槽的非常高效的,但是与回调函数相比,由于增加了灵活性,因此在速度上有所损失,这种损失相对来说是比较小的,通过在一台i586-133的机器上测试是10微秒(运行Linux),可见这种机制所提供的简洁性、灵活性还是值得的。一般来说,在实时系统中就要尽可能的少用信号与槽机制。

B、信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要避免在槽函数中再次发射所接收到的同样信号。

C、如果一个信号与多个槽相关联,那么当这个信号被发射时,与之相关的槽函数被调用的顺序将是随机的。

D、宏定义不能用在信号和槽的参数中。

moc工具不扩展#define,在信号和槽的参数中使用宏将不能正确地工作,不带参数是可以的。

E、构造函数不能用在signals或者slots声明区域内。

F、函数指针不能作为信号或槽的参数。

函数指针作为参数是不合语法,但可以使用typedef将函数指针类型重命名,使用函数指针类型作为参数是合语法的。

G、信号与槽不能有缺省参数。

H、信号与槽也不能使用模板类参数

可以使用typedef重命名模板类,重命名后的类型名可以作为信号与槽的参数

I、嵌套的类不能位于信号或槽区域内,也不能有信号或者槽。

J、友元声明不能位于信号或者槽声明区内,应该在普通C++的private、protected或者public区内进行声明。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT信号与槽机制 的相关文章

  • yii2学习笔记 --- 基础版配置链接多个数据库

    打开 config db php return class gt yii db Connection dsn gt mysql host localhost dbname yii2basic username gt root passwor
  • Qt数据库总结

    include
  • GD32F103配置PA15 PB3 PB4为普通IO

    PB3 PB4 PA15 作为普通IO时候 需要disable JTAG 释放出来 gpio pin remap config GPIO SWJ SWDPENABLE REMAP ENABLE 这个语句很重要 Function Key Sc
  • vue使用dhtmlx-gantt

    根据需求制作甘特图 绘制两时间段 相交地方为深颜色 没找到可以直接用的插件 于是就靠自己手动计算时间差与时间比例 但所得结果有部分误差 有更好组件欢迎交流 安装 npm install dhtmlx gantt save index js
  • Mysql数据库,查询结果为空值,如何处理?

    当sql查出空值的时候 如果想要获取 其中的值可能会出错 a res getString 字段 如果该字段的值是null 就会报错 所以需要在取字段值的时候做try catch 处理 try a res getString 字段 catch
  • unityShader物体表面流光效果

    本文转载自http blog csdn net lyh916 article details 51831720 参考链接 http liweizhaolili blog 163 com blog static 162307442012726
  • C++的排序

    C 十大排序 1 快速排序 2 插入排序 3 选择排序 4 冒泡排序 5 归并排序 6 堆排序 7 计数排序 8 桶排序 9 基数排序 10 希尔排序 11 补充 稳定排序 排序前后两个相等的数的相对位置不变 归并排序 冒泡排序 插入排序
  • On java 8 笔记——第六章 初始化和清理

    有两个安全性问题 初始化和清理 利用构造器保证初始化 在 Java 中 类的设计者通过构造器保证每个对象的初始化 如果一个类有构造器 那么 Java 会在用户使用对象之前 即对象刚创建完成 自动调用对象的构造器方法 从而保证初始化 构造器名
  • 宽度优先搜索(BFS)总结

    基本思想 宽度优先搜索一般用队列 queue 实现 且总是按层次的顺序进行遍历 解这类题的一般套路 定义一个结构体作为节点来存储信息 如保存横纵坐标x y 后续队列以该结构体为单位来存储 定义bool型数组 标记每个位置是否入过队列 定义增
  • 从好玩到好用:程序员用AI提效的那些事儿

    本片内容是 AI思维空间 ChatGPT纵横编程世界 点亮智慧火花的续作 主要记录组内开发小伙伴儿们在开发过程中的实际应用案例 记录典型案例 尽量不要和其他人重复 以解决开发过程中的实际问题为主 设计 方案 编码 测试 集成 部署等等 目的
  • python读取各种文件

    1 yaml文件 yaml文件的特点 1 数据结构 可以用类似大纲的 缩排 方式呈现 2 连续的项目通过减号 来表示 也可以用逗号来分割 3 键值对用冒号 来分隔 4 数组用 括起来 hash用 来括起来 写法 1 house yaml h
  • Bing 高级检索

    我常用的就这么几个 文章目录 使用空格表示与 site 返回属于指定网站的网页 使用filetype 限定文件类型 使用空格表示与 举例 如果直接输入搜索词 天气 返回 我们希望再精确一点 可以搜索 天气 贵州 这样就会优先搜到既有天气又有
  • 时间序列处理与应用

    时间序列处理与应用 介绍 一般情况下 在进行数据分析时 几乎都会遇到与时间序列相关的任务 例如 某企业的某项指标在第二天或者每周 又或每月等会发生什么 某款应用每天的下载量是多少等等 在本节实验中 将使用不同的方法来处理这些与时间序列相关的
  • 新版发布

    距离 v3 10 大版本发布刚过去一个月 v3 10 2 也要正式 release 了 快来看看它新增了哪些新功能以及修复了哪些问题吧 新功能 认证 品高云 OAuth 认证源支持 主机 支持自定义 PCI 透传设备的透传 主机 OpenS
  • 常用数据结构简讲

    在这里我会列举几个常用的STL数据结构与文档 更舒服的查看体验 1 v e c t o r vector vector 官网文档 可变长数组 动态数组 ST
  • c++基础--另类的分支结构

    前言 本节课讲的主要知识点是三目运算符和switch语句 同时也是我们分支结构部分的结尾内容 而从第三课开始到第五课 都是讲述分支结构的相关知识点 他们的特点都是相辅相成的 因此建议通读三篇文章 加强理解 同时做题也是必不可少滴 三目运算符
  • git commit --amend用法 合并commit

    反复修改并提交产生大量commit 正常第一次创建a txt提交 后创建b txt提交 会产生多个commit信息 git reset 回退到提交b txt之前 使用git commit amend打开后 操作同vim在其中可修改commi
  • Java静态变量、静态常量、静态方法

    Java静态变量 静态常量 静态方法 静态变量和静态方法都属于静态对象 在外部调用静态方法时 可以使用 类名 方法名 的方式 也可以使用 对象名 方法名 的方式 而实例方法只有后面这种方式 也就是说 调用静态方法可以无需创建对象 1 Jav
  • 程序人生:2023测试求职超千万,软件测试还能不能做?(过来人的建议)

    先说结论 可以 但是岗位要求会越来越高 只有不断的学习 提升自己的技术能力才是王道 测试的前景一定是光明的 岗位也是会越来越多 但是这绝不意味着我们可以在测试的行业里滥竽充数 提升自己的能力才是未来不被淘汰的关键 互联网的高速发展 对软件的
  • C语言宏定义、宏函数、内置宏与常用宏

    前言 在C语言中 变量类型 循环控制 基础语法等与其他高级语言基本无异 而C语言 C 特有的两把双刃剑指针和宏定义 宏函数使得C语言在底层开发中披荆斩棘 无所不能 这两个概念涉及范围比较广 其分支点也比较多 可谓星罗棋布 但这每颗星都足以照

随机推荐

  • JAVA中的成员变量和局部变量的区别

    成员变量与局部变量的区别 类中的位置不同 成员变量 类中 方法外 局部变量 方法内或方法声明上 作用范围不同 成员变量 类中 局部变量 方法中 初始化值的不同 成员变量 有默认值 局部变量 无默认值 练习 说明x和y和z哪个是局部变量哪个是
  • 【C++】红黑树

    文章目录 红黑树的概念 红黑树的性质 红黑树的节点定义 红黑树的结构 红黑树的插入操作 红黑树的验证 红黑树删除 红黑树模拟实现STL中的map与set 改造红黑树 map的模拟实现 set的模拟实现 红黑树的概念 红黑树 是一种二叉搜索树
  • 测试开发知识总结(一)

    本文内容顺序 测试基础理论 测试岗经常被问到的场景题 智力题 测试岗高频算法题 数据库 Linux知识点 常用自动化测试工具 1 Appium 官网 http appium io AppUI自动化测试 Appium 是一个移动端自动化测试开
  • TransUNet: Transformers Make Strong Encoders for Medical Image Segmentation

    TransUNet Transformers Make Strong Encoders for Medical Image Segmentation 发表时间 2021年2月 发表期刊 Arxiv Abstract 医学图像分割是发展医疗保
  • Spring- 上传文件 MultipartFile.transferTo() 报错 FileNotFoundException

    上传文件时 使用MultipartFile transferTo 将文件保存到本地路径 报错 java io IOException java io FileNotFoundException C Users XXXXX AppData L
  • vue单文件组件1(webpack打包)

    一 vue单文件组件开发流程 webpack打包 1 源文件目录结构 2 package json 3 webpack config js HTML Webpack Plugin依据html模板生成一个自动引用你打包后的文件 js或css
  • 【数据结构(C语言描述)】环形队列

    目录 一 基础知识 二 数组实现环队 2 1 初始化 2 2 判断环队是否为空 2 3 判断环队是否为满 2 4 入队 2 5 出队 2 6 取队头元素 2 7 取队尾元素 2 8 销毁环队 三 链表实现环队 3 1 初始化 3 2 判断环
  • STM32学习心得三十二:CAN通信基础知识、原理、配置及实验

    记录一下 方便以后翻阅 主要内容 1 CAN通信基础知识 2 STM32 CAN控制器简介 3 相关实验代码解读 参考资料 STM32中文参考手册 V10 第22章 控制器局域网 bxCAN 实验功能 CAN实验需要两个开发板 系统启动后
  • ctfshow-萌新-web1( 利用intval函数的特性获取敏感数据)

    ctf show 萌新模块的web1关 这一关考察的是intval 函数转换字符串时的特性以及SQL的拼接绕过 这一关直接就给了源码 并提示我们 id 1000 时 就是flag 先分析一下源码 首先是 intval 函数将参数id转换为数
  • PostgreSQL学习研究笔记(一)

    何为PostgreSQL PostgreSQL 是以加州大学伯克利分校计算机系开发的 postgres 版本 4 2 为基础的对象关系型数据库管理系统 PostgreSQL是最初的伯克利代码的开源继承者 任何人都可以以任何目的免费使用 修改
  • T-Kernel Error Code

    参考 tk errno h define E OK 0 Completed successfully define E SYS ERCD 5 0 System error define E NOCOP ERCD 6 0 Coprocesso
  • linux—通配符详解及总结

    本博客主要详解关于linux中常使用的通配符的知识点 主要分为三个步骤 通配符 和 的详细解释 举例截图说明 个人的总结理解 一 通配符 和 的详细解释 ps 因为通配符 中可添加很多变量 所以这里我会简单举出几个例子来说明 其他情况请类比
  • R 和 Rstudio 在线更新

    R 在线更新 最近安装 R 包的时候老是会遇到有些包不适应老版本 无奈还是更新了新的版本 卸载重装就太麻烦了 而且以前的包还需要重新加载 在线更新是最好的方法 可以直接在 Rstudio 中直接更新 直接运行以下命令就行 install p
  • Python还能这样学?独一档的学习路线与方法!两个月就能彻底掌握

    为什么要选择学习Python 我大学本专业当时学的是过时很久的工程物流管理 经常跟学长学姐们聊到他们的就业情况 然后自己也对未来的就业之路产生了很大的怀疑 后面经过一些了解 以及学长学姐的介绍 知道了Python 后面深入的了解了后 我果断
  • 基于Protege的知识建模实战

    一 Protege简介 用途和特点 1 Protege简介 Protege是斯坦福大学医学院生物信息研究中心基于Java开发的本体编辑和本体开发工具 也是基于知识的编辑器 属于开放源代码软件 这个软件主要用于语义网中本体的构建 是语义网中本
  • 华为OD机试真题B卷 Java 实现【停车场车辆统计】,附详细解题思路

    一 题目描述 特定大小的停车场 数组cars 表示 其中1表示有车 0表示没车 车辆大小不一 小车占一个车位 长度1 货车占两个车位 长度2 卡车占三个车位 长度3 统计停车场最少可以停多少辆车 返回具体的数目 二 输入描述 整型字符串数组
  • DHCP DNS 综合案例分析

    1 首先我们来配置一下192 168 1 2这台机器 1 1 操作系统 windows server 2003 R2 1 2 IP 192 168 1 2 24 GW 1922 168 1 1 DNS 192 168 1 2 注意 这台机器
  • 阿里云盘内测_【邀请码】阿里云盘内测码分享

    备受瞩目的阿里云网盘已在苹果App Store上架 并更名 阿里云盘 最新版本更名为v1 0 1 8 月下旬 阿里巴巴推出了一款名为 阿里云网盘 的独立 App 该应用开发者为阿里旗下的阿里云团队 定位是为 C 端用户提供可靠安全的存储备份
  • CUBEIDE 使用指南

    cubeIDE includes 下一直有一个错误的路径 如图 不知道什么原因引入了一个错误的路径怎么也消不掉 最后发现在工程文件里 用记事本等打开 cproject文件 删掉对应路径就好了 图是已经删掉的了 2 include 路径问题
  • QT信号与槽机制

    QT开发 QT信号与槽机制 一 QT消息模型 QT封装了具体操作系统的消息机制 遵循经典的GUI消息驱动事件模型 QT定义了与操作系统消息相关的自己的概念 即信号与槽 信号signal是由操作系统产生的消息 槽slot是程序中的消息处理函数