QT中的信号与槽的讲解

文章目录

  • 信号及其特点
  • 槽及其特点
  • 代码演示
    • 标准信号与标准槽函数
      • 方式一
      • 方式二
  • 自定义信号和槽
  • connect()函数
  • 信号和槽函数存在函数重载的情况下
  • Qt的信号槽机制注意事项

信号及其特点

信号:是一种特殊的函数,又称信号函数,俗称信号,用于在对象状态发生改变时通知其他对象。信号可以包含参数,但是它们不返回任何值。
信号必须位于类定义体中,形如:void clicked(bool checked = false); 返回类型必须为void,无参数时函数名后的括号也不能省略,没有函数体。就像成员函数的声明一样,与普通成员函数的区别,除了返回值只能是void外,还有就是信号没有函数体。
在这里插入图片描述
注意: Q_SIGNALS: 或 singals: 是不能够省略的。否则编译报错。

槽及其特点

槽:是一种接收信号的函数俗称槽函数,用于响应特定事件。槽函数可以被连接到一个或多个信号,并且可以有自己的参数和返回值。
与信号的最大区别就是 槽函数有函数体,返回值类型可以是任意类型。
槽函数的位置比较自由,可以位于类定义体中,可以是全局函数,还可以是lambda表达式。
在这里插入图片描述
注意: 有种情况下是不能省略这里的 public/protected/private slots: 或 public/protected/private Q_SLOTS: 下面讲方式一时再说

QT下自动的组件类中含有大量的信号和槽函数,又被称为标准信号,和标准槽函数。

代码演示

标准信号与标准槽函数

方式一

通过 QT creator 集成的 ui design下。演示 QT中的button组件中的常见的信号与槽函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
每一个 .ui 文件都对应一个相应的.h头文件,mainwindow.ui 对应的 .h文件为 ui_mainwindow.h。即将.ui文件的内容翻译为C/C++语言文件。
这两个文件都不能手动修改。通过 ui designer 修改界面后,.ui文件会自动更新,而调用build命令后 ui_mainwindow.h文件会根据相应的.ui文件自动更新。
在这里插入图片描述
在这里插入图片描述
也就是我们通过界面拖动的组件都会被转化相应的一个对象。然后对这个对象的属性进行赋值等操作。
在这里插入图片描述
在这里插入图片描述

方式二

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意: 上图在MainWindow类中自动生成的槽函函数声明,前面的public/private/protected slots: 是不能省略的,否则后面 点击按钮二时,不会触发槽函数的调用。
在这里插入图片描述
在这里插入图片描述
我们发现并没有显示自动生成connect()函数进行信号和槽的关联代码。而且手动也没有添加connect()函数进行信号和槽的关联代码。
点击按钮二时 确可以调到on_pushButton_clicked函数。可以看下图:关键点 就是这行代码:QMetaObject::connectSlotsByName(MainWindow);
对应的槽函数的名称 格式必须是:on_信号发送者名称_信号名称(参数)
在这里插入图片描述
这种方式也有一个缺点(正如:QT警告Slots named on_foo_bar are error prone),就是当我们修改按钮二对象的名称后,这里的槽函数名称里的对象名称(也就是信号发送者名称)不会自动发生变化(除非再通过 Go to slot… 再生成一个新的参函数),那么编译和运行期都不会报错,但是槽函数确不会被调用。演示如下:
在这里插入图片描述
此时点击 按钮二 无任何 输出。因为 on_pushButton_clicked()不能被调到。
除非再添加一个on_pushButton2_clicked()函数并实现。
在这里插入图片描述

自定义信号和槽

myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>class MyClass : public QObject
{Q_OBJECT
public:explicit MyClass(QObject *parent = nullptr);void custom_slot_0();//自定义槽函数signals:void custom_singal();//自定义信号public slots:void custom_slot_1();//自定义槽函数
};void custom_slot_2();//自定义槽函数#endif // MYCLASS_H

myclass.cpp

#include "myclass.h"
#include <QDebug>
MyClass::MyClass(QObject *parent): QObject{parent}
{}void MyClass::custom_slot_0()
{qDebug()<<"custom_slot_0";
}void MyClass::custom_slot_1()
{qDebug()<<"custom_slot_1";
}void custom_slot_2()
{qDebug()<<"custom_slot_2";
}

在主窗口类头文件中添加如下:
MyClass *myclass;
在这里插入图片描述
在主窗口类原文件中添加如下:
在这里插入图片描述
也可以写成下面这样:
在这里插入图片描述
在这里插入图片描述
在上方生成的槽函数函数体内,添加以下红框内容:
在这里插入图片描述
在这里插入图片描述

connect()函数

信号和槽关联是用QObject::connect()函数实现的,其基本格式是:

QObject::connect(sender,SIGNAL(singnal()),receiver,SLOT(slot())); //在QT4中,支持传递参数

connect()是QObject类的一个静态函数,而QObject是所有Qt类的基类,在实际调用时可以忽略前面的限定符:

connect(sender,SIGNAL(singnal()),receiver,SLOT(slot()));//在QT4中
connect(sender,SIGNAL(singnal()),receiver,SLOT(slot()));//在QT4中,支持传递参数

在QT5及以后版本支持如下格式:
连接信号和槽的connect()函数原型如下, 其中PointerToMemberFunction是一个指向函数地址的指针:

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);

使用connect()进行信号槽连接的注意事项:

connect函数相对于做了信号处理动作的注册
调用conenct函数的sender对象的信号并没有产生, 因此receiver对象的method也不会被调用
method槽函数本质是一个回调函数, 调用的时机是信号产生之后, 调用是Qt框架来执行的
connect中的sender和recever两个指针必须被实例化了, 否则conenct不会成功

虽然在QT5及QT6中也支持QT4中那种方式调用,但目前不推荐使用QT4的那种connect()函数了。
但是有个问题是QT5中新增的这样connect()函数,在给信号或者槽函数传参时不能直接传递,因为它们都是传递的函数地址,所以必确确保函数无参并且函数名是唯一的,否则存在二义性,编译不过。下面说下信号和槽函数存在重载的情况下,如何使用。

信号和槽函数存在函数重载的情况下

myclass.h中添加重载函数
在这里插入图片描述
myclass.cpp文件中:
在这里插入图片描述
mainwindow.cpp:主窗口实现类中
在这里插入图片描述
关于 成员函数的地址及全局函数的地址获取方式可以看 类中成员函数及普通函数地址获取方式
在这里插入图片描述

在这里插入图片描述

Qt的信号槽机制注意事项

要使用Qt中的信号槽机制,必须继承QObject类,还需要在类的定义中的第一行写上一个宏Q_OBJECT

class MyClass: public QObject
{Q_OBJECT // 没有这个宏, 信号槽机制还是不能使用...
}

如果没有直接继承QObject,而是继承了一些继承QObject类的其他类也可以,比如QWidget类是QObject的子类,再有个类继承QWidget也能使用信号槽的机制。还比如QMainWindow类,QMainWindow继承QWidget类。再有个类继承QMainWindow同样也能使用信号槽的机制。

还有一点是,槽函数的参数个数要小于等于信号函数的参数个数。即如果信号函数是无参的,则与其绑定的槽函数也不能写形式参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

<软考高项备考>《论文专题 - 37 采购管理(1) 》

1 成本管理基础 1.1 写作要点 过程定义、作用写作要点、思路规划采购管理规划采购管理是记录项目采购决策、明确采购方法&#xff0c;及识别潜在卖方的过程。作用:确定是否从项目外部获取货物和服务&#xff0c;如果是&#xff0c;则还要确定将在什么时间、以什么方式获取什么…

项目实战--Message Queue

一. 概念篇 我们在学习多线程的时候,学习过生产者-消费者模型,为了实现解耦合和削峰填谷,引入了阻塞队列. 在实际的后端开发中,跨主机之间使用生产者消费者模型,也是非常普遍的需求,因此,阻塞队列会被封装成一个独立的服务器程序,实现更丰富的功能.这样的程序称为"消息队列…

Grafana监控数据可视化

Grafana 是一个可视化面板&#xff0c;有着非常漂亮的图表和布局展示&#xff0c;功能齐全的度量仪表盘和图形编辑器&#xff0c;支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作为数据源&#xff0c;比 Prometheus 自带的图表展示功能强大太多&am…

运行时错误‘53’文件未找到:MathPage.WLL,安装MathType后Word不能复制粘贴问题的解决

两步解决&#xff1a; 1. 打开Word-->文件-->选项-->信任中心-->信任中心设置-->受信任位置&#xff0c;解决宏问题 添加如下受信任位置&#xff0c; 我的路径&#xff1a;C:\Program Files\Microsoft Office\root\Office16\STARTUP\ 2. 找到MathType下的MathT…

Unity关于动画混合树(Blend Tree)的使用

在动画与动画的切换过程中&#xff0c;常因为两个动画之间的差距过大&#xff0c;而显得动画的切换很不自然。 这时候就需要动画混合树Blend Tree这个功能。使用混合树可以将多个动画混合在一起&#xff0c;例如在处理角色的移动中&#xff0c;走动画与跑动画切换的时候&#x…

vue3引入百度地图(两种方法)

首先要有百度开放平台并进行注册&#xff0c;不懂看这里 ### 第一种方法 地图引入流程 安装vue-baidu-map-3x插件 参考官网地址&#xff1a;快速上手 | vue-baidu-map-3x npm install vue-baidu-map-3x --save 在public/index.html文件中引入 <!-- 百度地图 --> &…

pytorch03:transforms常见数据增强操作

目录 一、数据增强二、transforms--Crop裁剪2.1 transforms.CenterCrop2.2 transforms.RandomCrop2.3 RandomResizedCrop2.4 FiveCrop和TenCrop 三、transforms—Flip翻转、旋转3.1RandomHorizontalFlip和RandomVerticalFlip3.2 RandomRotation 四、transforms —图像变换4.1 t…

HarmonyOS4.0系统性深入开发09卡片使用动效能力

卡片使用动效能力 ArkTS卡片开放了使用动画效果的能力&#xff0c;支持显式动画、属性动画、组件内转场能力。需要注意的是&#xff0c;ArkTS卡片使用动画效果时具有以下限制&#xff1a; 名称参数说明限制描述duration动画播放时长限制最长的动效播放时长为1秒&#xff0c;当…

SpringMVC源码解析——DispatcherServlet的逻辑处理

DispatcherServlet类相关的结构图如下&#xff1a; 其中jakarta.servlet.http.HttpServlet的父类是jakarta.servlet.GenericServlet&#xff0c;实现接口jakarta.servlet.Servlet。我们先看一下jakarta.servlet.Servlet接口的源码如下&#xff1a; /*** 定义所有servlet必须实…

【网络安全】网络隔离设备

一、网络和终端隔离产品 网络和终端隔离产品分为终端隔离产品和网络隔离产品两大类。终端隔离产品一般指隔离卡或者隔离计算机。网络隔离产品根据产品形态和功能上的不同&#xff0c;该类产品可以分为协议转换产品、网闸和网络单向导入产品三种。 图1为终端隔离产品的一个典型…

dash 中的模式匹配回调函数Pattern-Matching Callbacks 8

模式匹配 模式匹配回调选择器 MATCH、ALL 和 ALLSMALLER 允许您编写可以响应或更新任意或动态数量组件的回调函数。 此示例呈现任意数量的 dcc. Dropdown 元素&#xff0c;并且只要任何 dcc. Dropdown 元素发生更改&#xff0c;就会触发回调。尝试添加几个下拉菜单并选择它们的…

Grafana增加仪表盘

1.Grafana介绍 grafana 是一款采用Go语言编写的开源应用&#xff0c;主要用于大规模指标数据的可视化展现&#xff0c;是网络架构和应用分析中最流行的时序数据展示工具&#xff0c;目前已经支持绝大部分常用的时序数据库。 Grafana下载地址&#xff1a;https://grafana.com/g…

burpsuite的安装与介绍

安装(挑一个你喜欢的版本安装就行) 编程环境安装指南:Java、Python 和 Burp Suite抓包工具_burpsuite和java-CSDN博客 简介 Burp Suite是一个用于攻击Web应用程序的集成平台。它集成了多种渗透测试组件,能够帮助我们更好地完成对Web应用的渗透测试和攻击,无论是自动化还…

基于CNN神经网络的手写字符识别实验报告

作业要求 具体实验内容根据实际情况自拟&#xff0c;可以是传统的BP神经网络&#xff0c;Hopfield神经网络&#xff0c;也可以是深度学习相关内容。 数据集自选&#xff0c;可以是自建数据集&#xff0c;或MNIST&#xff0c;CIFAR10等公开数据集。 实验报告内容包括但不限于&am…

[C#]opencvsharp进行图像拼接普通拼接stitch算法拼接

介绍&#xff1a; opencvsharp进行图像拼一般有2种方式&#xff1a;一种是传统方法将2个图片上下或者左右拼接&#xff0c;还有一个方法就是融合拼接&#xff0c;stitch拼接就是一种非常好的算法。opencv里面已经有stitch拼接算法因此我们很容易进行拼接。 效果&#xff1a; …

PayPal账户被封是因为什么?如何解决?

Paypal作为跨境出海玩家最常用的付款工具之一&#xff0c;同时也是最容易出现冻结封号现象。保障PP账号安全非常重要&#xff0c;只有支付渠道安全&#xff0c;才不会“白费力气”&#xff0c;那么最重要的就是要了解它的封号原因以做好规避。 一、Paypal账号被封原因 1、账号…

FreeRTOS列表与列表项相关知识总结以及列表项的插入与删除实战

1.列表与列表项概念及结构体介绍 1.1列表项简介 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向环形链表 1.2 列表、列表项、迷你列表项结构体 1&#xff09;列表结构体 typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VAL…

List常见方法和遍历操作

List集合的特点 有序&#xff1a; 存和取的元素顺序一致有索引&#xff1a;可以通过索引操作元素可重复&#xff1a;存储的元素可以重复 List集合的特有方法 Collection的方法List都继承了List集合因为有索引&#xff0c;所以有了很多操作索引的方法 ublic static void main…

挑战 ChatGPT 和 Google Bard 的防御

到目前为止&#xff0c;科学家已经创建了基于人工智能的聊天机器人&#xff0c;可以帮助内容生成。我们还看到人工智能被用来创建像 WormGPT 这样的恶意软件&#xff0c;尽管地下社区对此并不满意。但现在正在创建聊天机器人&#xff0c;可以使用生成人工智能通过即时注入活动来…

OpenHarmony之分布式软总线

背景概述 从之前的文档(OpenHarmony之内核层)可知 分布式软总线是多设备终端的统一基座&#xff0c;为设备间的无缝互联提供了统一的分布式通信能力&#xff0c;能够快速发现并连接设备&#xff0c;高效地传输任务和数据。 分布式软总线实现近场设备间统一的分布式通信管理能…