【Qt】信号、槽

目录

一、信号和槽的基本概念

二、connect函数:关联信号和槽

例子:

三、自定义信号和槽

1.自定义槽函数

2.自定义信号函数

例子:

四、带参的信号和槽

例子:

五、Q_OBJECT宏

六、断开信号和槽的连接

例子:

七、lambda作为槽函数

例子:

qt中关于lambda引用传递捕捉


一、信号和槽的基本概念

1.信号

信号(signal)是由于用户对窗口或控件进行某些操作,导致窗口或控件产生某种特定事件,这时窗口类/控件类会发出信号给接收信号的控件对象。

2.槽

槽(slot)是对信号响应的函数。槽就是一个函数,与一般C++函数一样,可以定义在类任何访问权限下(public、protected、private),可以带参,可以重载,但是不能有默认参数。槽函数与普通函数不同的点是:槽函数可以关联某个信号,当该信号发出时关联的槽函数会自动执行。

信号和槽要解决的问题就是响应用户的操作

下面有一个例子:我们在窗口中创建一个按钮,点击该按钮控件该按钮上的内容会在"hello world

"和"hello qt"中间切换。

使用拖拽控件的方式构建图形界面:

当使用拖拽控件的方式构建图形界面时,每个控件对象都有下图中右下角中红圈圈的部分:objectName这个里面的内容就是通过拖拽创建的控件对象的名字,可以对该名字进行修改。

在Qt中,QObject类提供了一个静态成员函数connect,该函数用于关联信号函数和槽函数。

值得注意的是:如果使用这种拖拽方式构建图形界面,此时创建的控件对象都会在Widget类中的成员变量ui所指向的类中,因此在Widget类中访问以拖拽方式创建的控件对象时,要使用ui指针访问。

使用纯代码方式构建图形界面:

 值得注意的是:如果按照纯代码方式进行构建,那么我们应该将按钮控件对象声明为Widget类的成员变量,然后再Widget的构造函数中定义,这样就可以在槽函数中对该按钮对象进行操作。 

qt中类的关系:

QObject是Qt内置的父类,Qt中大多数类都是间接或直接继承自QObject。比如QWidget就是继承自QObject因此继承自QObject的类都可以使用QObject中的静态成员函数connect以及QObject的其他成员函数。

二、connect函数:关联信号和槽

例子:

现在写一个qt项目:通过点击窗体控件中的一个按钮控件使窗体控件关闭。

如下:发送信号的控件对象是button按钮,信号函数是QPushButton::clicked,接收信号的控件是窗口Widget,槽函数是Widget::close,close函数其实是QWidget类的成员函数,由于类Widget继承自QWidget因此Widget可以使用QWidget中的所有方法。

需要注意的是:使用connect函数关联信号和槽时,信号函数必须是发送信号的控件对象的成员函数;槽函数必须是接收信号的控件对象的成员函数。

通过图标判断信号函数和槽函数:

 像信号发射的图标是信号函数,比如这个clicked函数;像锯齿形的是槽函数,比如这个click。

三、自定义信号和槽

qt内部已经有大量现成的信号函数和槽函数,但是有些时候需要我们自己定义信号函数和槽函数。

1.自定义槽函数

1.自定义槽函数的返回值是void,需要声明和实现

2.可以有参数,可以被重载。

3.可以在public slots、protected slots、priavte slots下,也允许写在public下声明。

C++纯代码(即使用connect函数)方式连接信号和槽。

上面已有这种方式实现的代码。

UI设计窗口的方式自动连接信号和槽。

1.选中拖拽的控件点击右键,点击转到槽

2.选择要连接的信号

3.qt会自动生成一个函数,通过该函数的名字自动连接信号和槽

qt自动生成的这个函数名是具有格式规则的。对于函数名on_pushButton_clicked,on_后面就是发出信号的控件对象名字,clicked就是该控件发送的信号函数(一旦用户触发pushButton对象中的QPushButton::clicked,pushButton就会发送信号)。处理信号的动作就是在这个on_pushButton_clicked函数里实现。

2.自定义信号函数

1.自定义信号函数的返回值是void,只需声明,不需要定义,qt会自动帮我们完成定义。

2.可以有参数,可以被重载。

3.必须在signals后声明。

例子:

我们通过自定义信号完成一个简单的需求:但我们点击按钮控件后,窗口标题需要发生改变。


这有个emit其实是可以不写的。

四、带参的信号和槽

对于不带参的信号和槽前面已经有了。

1.信号函数和槽函数的参数类型必须一致,个数可以不一致(信号函数的参数个数多于槽函数)。

2.发射信号的时候,就可以给信号函数传递参数,该信号函数被执行完成后,会将这个参数传递给对应的槽函数。

例子:

实现一个功能:通过UI设计窗口创建两个按钮控件pushButton_1和pushButton_2。点击pushButton_1后窗口标题变为"标题一",点击pushButton_2窗口标题变为"标题二"。如下:

如果信号和槽连接,允许两者的参数个数可以不一致(信号函数的参数个数多于槽函数),但参数类型必须一致,这样的设计相较于参数数量必须一致的好处是什么?

情况:一个槽可能连接多个信号,如果要求参数必须一致才可连接,信号绑定槽的要求就会变高,如果一个槽的参数个数是1,那么参数个数是2的信号就无法绑定槽,尽管此时信号的第一个参数类型和这个槽的参数类型相同,也无法进行连接,这就导致了信号和槽之间的连接不够灵活。

五、Q_OBJECT宏

Qt中如果要让某个类可以使用信号和槽(可以在这个类中定义信号函数和槽函数),则必须要在这个类的最开始加上Q_OBJECT。

qt创建项目后会自动qt会自动帮我们加上了这个宏,如果没加这个宏使用了信号槽则会编译出错。

六、断开信号和槽的连接

使用disconnect断开信号和槽的连接,disconnect和connect在接口上的用法基本一致。断开信号和槽的连接比较少见,调用disconnect一般是为了更换一个信号连接的槽函数,disconnect后这个信号就可以连接其他新的槽函数了。

注意:

qt中的信号和槽中支持一个信号绑定多个槽一个槽被多个信号绑定

例子:

现在要设计这样一个功能:在UI窗口设计中创建按钮pushButton和pushButton_1,点击pushButton后将窗口标题改为"这是旧窗口标题",点击pushButton_1后,然后每次点击pushButton窗口标题变为”这是新窗口标题“。如下:

 

七、lambda作为槽函数

例子:

这个例子中lambda通过值传递捕捉了外层作用与的所有变量。

qt中关于lambda引用传递捕捉

在使用lambda表达式时要注意捕捉到的变量的生命周期,如果捕获了一个指针,该指针指向的空间在lambda访问的时候已经被释放,那么就会出现访问错误。

如果上面的例子中的lambda采用引用传递捕捉会出现什么情况?

当按钮button被点击,发送信号,则槽函数即lambda表达式会被执行,此时无法执行button->move(100,100)及以下代码。

原因:由于button(是一个指针变量,存的是地址)是一个栈区的变量,Widget的构造函数调用完后,button变量会被销毁,因此如果槽函数被触发执行,捕捉的是button的引用,想一下button变量都销毁了,那这个捕捉的引用也就指向垃圾空间了,但是如果button是Widget类的成员变量那么就不会出现错误。

Qt 5及更高版本的,都会默认在qt项目文件中.pro文件中加上CONFIG += c++11,但是Qt 5以下的版本则不会默认加,加上后就可以按照C++11来编译了。

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

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

相关文章

数据库密码加密

数据库密码加密 简单来说: 我们会经常看到重置密码,小时候就会有疑惑,为什么不直接告诉我们密码,原来服务器自己也不知道。 我们都知道密码在数据库中不能明文,不然风险很高,有数据库权限的人还可能恶意利…

PCIE概述

PCIE概述 文章目录 PCIE概述前言一、应用场景二、PCIE理论2.1 硬件2.2 拓扑结构:处理器和设备之间的关系2.3 速率2.4 层次接口2.5 四种请求类型2.5.1 bar空间2.5.2 memory2.5.3 IO2.5.4 configuration2.5.5 message 前言 参考链接: pcie总线知识点解析 …

Android Studio创建新项目并引入第三方so外部aar库驱动NFC读写器读写IC卡

本示例使用设备:https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1bbW3AUC&ftt&id615391857885 一、打开Android Studio,点击 File> New>New project 菜单,选择 要创建的项目模版,点击 Next 二、输入项目名称…

NX系列-使用 `nmcli` 命令创建 Wi-Fi 热点并设置固定 IP 地址

使用 nmcli 命令创建 Wi-Fi 热点并设置固定 IP 地址 一、前言 在一些场景下,我们需要将计算机或嵌入式设备(例如 NVIDIA Orin NX)转换为 Wi-Fi 热点,以便其他设备(如手机、笔记本等)能够连接并使用该设备…

AngularJS 与 SQL 的集成应用

AngularJS 与 SQL 的集成应用 引言 在当今的Web开发领域,AngularJS 和 SQL 是两种非常重要的技术。AngularJS,作为一个强大的前端框架,能够帮助开发者构建复杂且高性能的客户端应用。而SQL(Structured Query Language),作为一种广泛使用的数据库查询语言,是管理关系型…

用docker快速安装电子白板Excalidraw绘制流程图

注:本文操作以debian12.8 最小化安装环境为host系统。 一、彻底卸载原有的残留 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 二、设置docker的安装源 # Add Dockers official G…

C++趟坑学习-new,delete,虚析构函数

#include <iostream> using namespace std;class Resource { public:Resource() { cout << "Resource constructed" << endl; }~Resource() { cout << "Resource destructed" << endl; } };int main() {// 动态分配一个包含…

Spring Mvc面试题(常见)

1 Spring MVC的执行流程 用户发起请求,请求先被Servlet拦截以后,转发给SpringMVC框架SpringMVC 里面的DispatcherServlet(核心控制器) 接收到请求,并转发给HandlerMappingHandlerMapping负责解析请求,根据请求信息和配置信息找到匹配的Controller类(当这里有配置拦截器,会…

mac 如何开启指定端口供外部访问?

前言 需要 mac 上开放指定端口&#xff0c;指定 ip 访问 解决 在 macOS 上开放一个端口&#xff0c;并指定只能特定的 IP 访问&#xff0c;可以使用 macOS 内置的 pfctl(Packet Filter)工具来实现。 1、 编辑 pf 配置文件&#xff1a; 打开 /etc/pf.conf 文件进行编辑。 可以使…

如何设置Jsoup解析京东商品详情?

在数字化时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是在电商领域。通过爬虫技术&#xff0c;我们可以从网站中提取有价值的信息&#xff0c;用于市场分析、价格监控等。Java作为一种成熟且功能强大的编程语言&#xff0c;拥有丰富的库支持&#xff0c;使其成为编写爬…

STM32读写flash注意事项

STM32读写Flash时,需要注意以下事项以确保操作的正确性和可靠性: 一、写入操作注意事项 擦除操作: STM32内置Flash的写入操作必须遵循“先擦除,后写入”的原则。擦除操作以页(或扇区)为单位进行,这意味着在写入新数据之前,需要擦除整个页(或扇区)。写入单位: 写入操…

练习题:一维数组

练习题 第一题 键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 代码 #include <stdio.h>int arr_home01() {int arr[10];int i,j,temp;printf("请输入10个测试整数&#xff1a;\n");int len sizeof(arr) / sizeof(arr[0]);for(i 0;i < …

手眼标定工具操作文档

1.手眼标定原理介绍 术语介绍 手眼标定&#xff1a;为了获取相机与机器人坐标系之间得位姿转换关系&#xff0c;需要对相机和机器人坐标系进行标定&#xff0c;该标定过程成为手眼标定&#xff0c;用于存储这一组转换关系的文件称为手眼标定文件。 ETH&#xff1a;即Eye To …

PyTorch中apex的安装方式

apex是NVIDIA开发的基于PyTorch的混合精度训练加速神器&#xff0c;能够增加运算速度&#xff0c;并且减少显存的占用。 Github地址&#xff1a;https://github.com/NVIDIA/apex官方教程&#xff1a;https://nvidia.github.io/apex/ 安装方式 需要注意的是apex的安装不能通过…

【YashanDB知识库】YCP单机部署离线升级-rpc升级方式详细步骤

前提&#xff1a;每个被纳管的主机必须开放9072端口 1、先执行备份操作 #ycm安装路径为默认/opt/ycmcd /opt/ycm/ycm/scripts[yashanecs-ba94-0001 scripts]$ sudo ./backup.sh -n ycm -i /opt/ycm/ycm -c yashandb -y /home/yashan/yasdb_home/yashandb/22.2.11.105 --cata-…

MyBatis一二级缓存的区别?

大家好&#xff0c;我是锋哥。今天分享关于【MyBatis一二级缓存的区别&#xff1f;】面试题。希望对大家有帮助&#xff1b; MyBatis一二级缓存的区别&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 的缓存机制分为 一级缓存 和 二级缓存&…

mybatis 的动态sql 和缓存

动态SQL 可以根据具体的参数条件&#xff0c;来对SQL语句进行动态拼接。 比如在以前的开发中&#xff0c;由于不确定查询参数是否存在&#xff0c;许多人会使用类似于where 1 1 来作为前缀&#xff0c;然后后面用AND 拼接要查询的参数&#xff0c;这样&#xff0c;就算要查询…

某名校考研自命题C++程序设计——近10年真题汇总(下)

第二期&#xff0c;相比上一贴本帖的题目难度更高一些&#xff0c;我当然不会告诉你我先挑简单的写~ 某名校考研自命题C程序设计——近10年真题汇总&#xff08;上&#xff09;-CSDN博客文章浏览阅读651次&#xff0c;点赞9次&#xff0c;收藏13次。本帖更新一些某校的编程真题…

【网络】传输层协议UDP/TCP网络层IP数据链路层MACNAT详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.传输层协议 UDP 1.1 传输层 1.2 端口号 1.3 UDP 协议 1.3.1 UDP 协议端格式 1.3.2 UDP 的特点 1.3.3 面向数据报 1…

Python与数据库Mysql连接及操作方法

Python与数据库Mysql连接及操作方法 目录 Python与数据库Mysql连接及操作方法配置pip连接使用IP地址连接配置后使用机名连接 执行操作 配置pip 连接需要第三方库—pymysql pip install mysql连接 使用IP地址连接 格式&#xff1a; pymysql.connect( user ’ 用户名root’ …