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同样也能使用信号槽的机制。
还有一点是,槽函数的参数个数要小于等于信号函数的参数个数。即如果信号函数是无参的,则与其绑定的槽函数也不能写形式参数。
相关文章:

QT中的信号与槽的讲解
文章目录 信号及其特点槽及其特点代码演示标准信号与标准槽函数方式一方式二 自定义信号和槽connect()函数信号和槽函数存在函数重载的情况下Qt的信号槽机制注意事项 信号及其特点 信号:是一种特殊的函数,又称信号函数,俗称信号,…...
RNN文本分类任务实战
递归神经网络 (RNN): 定义:RNN 是一类专为顺序数据处理而设计的人工神经网络。 顺序处理:RNN 保持一个隐藏状态,该状态捕获有关序列中先前输入的信息,使其适用于涉及顺序依赖关系的任务。词嵌入…...

【算法系列 | 12】深入解析查找算法之—斐波那契查找
序言 心若有阳光,你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。 我们一起努力,成为更好的自己! 今天第12讲,讲…...

全新的C++语言
一、概述 C 的最初目标就是成为 “更好的 C”,因此新的标准首先要对基本的底层编程进行强化,能够反映当前计算机软硬件系统的最新发展和变化(例如多线程)。另一方面,C对多线程范式的支持增加了语言的复杂度࿰…...

three.js 多通道组合
效果: 代码: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div style"border: 1px so…...
编程笔记 html5cssjs 022 HTML表单概要
编程笔记 html5&css&js 022 HTML表单概要 一、<form> 元素二、HTML Form 属性三、操作小结 网页光是输出没有输入可不行,因为输出还是比输入容易,所有就先接触输出,后学习输入。html用来输入的东西叫“表单”。 HTML 表单用于搜…...

三子棋(c语言)
前言: 三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小,三子棋在很多时候会出现和…...

MySQL-DCL
DCL是数据控制语言,用来管理数据库用户,控制数据库的访问权限。 管理用户:管理哪些用户可以访问哪些数据库 1.查询用户 USE mysql; SELECT * FROM user; 注意: MySQL中用户信息和用户的权限信息都是记录在mysql数据库的user表中的…...
QT开源类库集合
QT开源类库集合 一、自定义控件 QSintQicsTableLongscroll-qtAdvanced Docking System 二、图表控件 QwtQCustomPlotJKQTPlotter 三、网络 QHttpEngineHTTP 四、 音视频 vlc-qt 五、多线程 tasks 六、数据库 EasyQtSql 一、自定义控件 1. QSint 源代码地址:QSint&…...
C++ STL(2)--算法(2)
算法(2)----STL里的排序函数。 1. sort: 对容器或普通数组中指定范围内的元素进行排序,默认进行升序排序。 sort函数是基于快速排序实现的,属于不稳定排序。 只支持3种容器:array、vector、deque。 如果容器中存储的是自定义的对象ÿ…...

格密码基础:对偶格(超全面)
目录 一. 对偶格的格点 1.1 基本定义 1.2 对偶格的例子 1.3 对偶格的图形理解 二. 对偶格的格基 2.1 基本定义 2.2 对偶格的格基证明 三. 对偶格的行列式 3.1 满秩格 3.2 非满秩格 四. 重复对偶格 五. 对偶格的转移定理(transference theoremÿ…...
ECMAScript简介及特性
ECMAScript是一种由ECMA国际(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范,JavaScript在它基础上进行了自己的封装。ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。 ECMAScript的…...

csdn中的资源文件如何删除?
csdn中的资源文件如何删除? 然后写文章的时候 点击资源绑定,解锁资源,就可以再次上传。...
NA原理及配置
在IP地址空间中,a;b;c类地址中各有一部分地址,被称为私有IP地址(私网地址),其余的为公有IP地址(公网地址) A:10.0.0.0 - 10.255.255.255 --- 相当于1条A类网段…...

解决:TypeError: ‘tuple’ object does not support item assignment
解决:TypeError: ‘tuple’ object does not support item assignment 文章目录 解决:TypeError: tuple object does not support item assignment背景报错问题报错翻译报错位置代码报错原因解决方法方法一:方法二:今天的分享就到…...

vue3项目中axios的常见用法和封装拦截(详细解释)
1、axios的简单介绍 Axios是一个基于Promise的HTTP客户端库,用于浏览器和Node.js环境中发送HTTP请求。它提供了一种简单、易用且功能丰富的方式来与后端服务器进行通信。能够发送常见的HTTP请求,并获得服务端返回的数据。 此外,Axios还提供…...

基础语法(一)(1)
常量和表达式 在这里,我们可以把Python当成一个计算器,来进行一些算术运算 例如: print(1 2 - 3) print(1 2 * 3) print(1 2 / 3)注意: print是一个python内置的函数,这个稍后我们会进行介绍 可以使用-*/&…...

YOLOv8模型yaml结构图理解(逐层分析)
前言 YOLO-V8(官网地址):https://github.com/ultralytics/ultralytics 一、yolov8配置yaml文件 YOLOv8的配置文件定义了模型的关键参数和结构,包括类别数、模型尺寸、骨架(backbone)和头部(hea…...

【大数据】Zookeeper 集群及其选举机制
Zookeeper 集群及其选举机制 1.安装 Zookeeper 集群2.如何选取 Leader 1.安装 Zookeeper 集群 我们之前说了,Zookeeper 集群是由一个领导者(Leader)和多个追随者(Follower)组成,但这个领导者是怎么选出来的…...
Redis 过期策略
我们在set key的时候可以设置key的过期时间,哪redis是怎么处理过期的key的呢? 有三种过期策略 定时过期:每个设置过期时间的key会创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...