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,一经查实,立即删除!

相关文章

了解CPU架构

uname -m # Linux查看CPU硬件架构 CPU 的指令集架构(Instruction Set Architecture)&#xff08;ISA&#xff09; CPU 的指令集架构&#xff0c;定义了 CPU 如何解析二进制代码中的 1 和 0。 ISA 主要根据 内存总线的宽度 分为至少两个子集。内存总线的宽度指的是 CPU 和 RAM …

java常见面试题:请解释一下Java中的常用安全框架,如Spring Security、Shiro等。

下面我将详细介绍Java中的两个常用安全框架&#xff1a;Spring Security和Shiro。 1. Spring Security Spring Security是一个强大的安全框架&#xff0c;它为基于Spring的应用程序提供了全面的安全解决方案。以下是Spring Security的一些主要特点&#xff1a; 主要特点&…

《妙趣横生的算法》(C语言实现)-第10章算法设计与数据结构面试题精粹

【10-1】输入一个字符串并将它输出&#xff0c;以ctrlz组合键表示输入完毕&#xff0c;要求将输入的字符串中多于1个的连续空格符合并为1个。 //10-1 2023年12月30日17点11分-17点18分 # include <stdio.h> int main() {char c;c getchar();//scanf("%c", &a…

【数据库设计和SQL基础语法】--用户权限管理--数据备份和恢复策略

一、引言 数据备份和恢复是数据库管理中至关重要的任务&#xff0c;对于确保数据安全性和业务连续性具有重大的意义。以下是一些关键的重要性方面&#xff1a; 防止数据丢失&#xff1a; 数据备份是防止因硬件故障、人为错误、恶意攻击或其他意外事件导致数据丢失的主要手段。…

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

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

16. Mysql 自定义函数

文章目录 概述常见操作创建自定义函数自定义函数局部变量定义和赋值查看自定义函数删除自定义函数使用自定义函数 扩展-流程控制精选示例总结参考资料 概述 自定义函数&#xff0c;顾名思义就是是MySQL中用户自定义的函数&#xff0c;用于执行特定的操作或计算&#xff0c;并返…

项目实战--Message Queue

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

GTK4 环境配置

1 安装gtk4包裹: # sudo yum install gtk4 gtk4-devel gtk4-devel-docs devhelp glib2 glib2-devel glib2-doc 2 安装 glade 4 git clone https://github.com/ag-python/cambalache.git 记住 把软件目录 复制到 一个你不会移动删除的地方(千万别删除这个软件文件夹 因为运行…

面试要点,算法,数据结构等练习大全

有趣的算法&#xff0c;面试常常碰到&#xff0c;多种语言实现~ 1 从数组中找出两个数字使得他们的和是给定的数字 tags: #hash 使用一个散列&#xff0c;存储数字和他对应的索引。然后遍历数组&#xff0c;如果另一半在散列当中&#xff0c;那么返回 这两个数的索引&#x…

Grafana监控数据可视化

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

LeetCode第69题 - x 的平方根

题目 解答 方案一 class Solution {public int mySqrt(int x) {if (x 0) {return 0;}if (x < 4) {return 1;}for (int i 2, length Math.min(46342, x / 2 2); i < length; i) {int value i * i;if (value x) {return i;}if (value > x || value < 0) {re…

MySQL中常用的数据类型

整型 int 有符号范围: -2147483648 ~ 2147483647 int unsigned 无符号范围: 0 ~ 4294967295 int(5) zerofill 仅用于显示&#xff0c;当不满足5位时&#xff0c;按照左边补0&#xff0c;例如: 00002满足时&#xff0c;正常显示 tinyint[(m)] [unsigned] [zerofill] 有符号&a…

运行时错误‘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…

数据结构算法-穷举搜索算法

引言 穷举搜索是一种基本的搜索策略&#xff0c;其基本思想是逐一检查所有可能的解&#xff0c;直到找到一个有效的解或确定不存在解为止。在现实生活中&#xff0c;穷举搜索的应用非常广泛&#xff0c;以下是一些例子&#xff1a; 密码破解&#xff1a;在密码学中&#xff0…

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;当…

【华为数据之道学习笔记】8-3异常数据监控

质量控制是通过监控质量形成过程&#xff0c;消除全过程中引起不合格或不满意效果的因素&#xff0c;以达到质量要求而采用的各种质量作业技术和活动。要保证最终交付质量&#xff0c;必须对过程进行质量控制&#xff0c;通常是在过程中设置关键质量控制点。例如&#xff0c;可…

Dockerfile学习文档

Dockerfile详解 Dockerfile是一个组合映像命令的文本&#xff1b;可以使用在命令行中调用任何命令&#xff1b;Docker通过dockerfile中的指令自动生成镜像。 通过docker build -t repository:tag ./ 即可构建&#xff0c;要求&#xff1a;./下存在Dockerfile文件 之前我们聊的…