当前位置: 首页 > news >正文

Qt信号与槽

我们在使用Qt的时候,不使用Qt Designer 的方式进行开发,使用ui文件,信号与槽的连接方式是生成代码之后才能在setupUi函数里才能看到,或者需要进入Ui设计器里的信号槽模式里才能看到信号槽的连接。所以我们最好使用代码绘制界面。

一.Qt信号与槽机制

信号(Signal)就是在特定情况下被发射的事件,槽(Slot)就是对信号响应的函数。槽函数与一般函数不一样的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

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

QObject::connect(sender,SIGNAL(signal()),recevier,SLOT(slot));

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

connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

其中,sender 是发射信号的对象的名称,signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。receiver 是接收信号的对象名称,slot() 是槽函数 的名称,需要带括号,有参数时还需要指明参数。

当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型,但可以不写参数名称。

一个信号可以连接另外一个信号(说明了 connect 万物皆可连,非常好用!),例如:

connect(pushButton,SIGNAL(objectNameChanged(QString)),this, SIGNAL(windowTitelChanged(QString)));

这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。

严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。 如果不匹配,会出现编译错误或运行错误。

在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT(特别重要)。

当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。 只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。

总结如下图,可以看到发送者与发送的信号是在一起的,接收者与接收的信号/槽是在一起 的。它们不能在 connect()方法里写乱顺序!由发送者发送出信号到接收者用信号/槽接收。

信号槽连接的方法已经讲解过了,接下来讲解一下断开连接的方法,使用disconnect()。

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

信号与槽机制是 Qt GUI 编程的基础,使用信号与槽机制可以比较容易地将信号与响应代码关联起来。

二. 如何在项目里创建信号

信号只需声明,无需定义。所以我们只需要在 mianwindow.h 里声明信号即可。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
/*引入 QPushButton */
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:/* 声明一个信号,只需声明,无需定义 */void pushButtonTextChanged();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

三. 如何在项目中创建槽

创建槽的方法也很简单,也是直接在 mianwindow.h 里直接声明槽,在 mianwindow.cpp 里 实现槽的定义,声明槽必须写槽的定义(定义指函数体的实现),否则编译器编译时将会报错。

槽有以下特点:

  1. 槽可以是任何成员函数,普通全局函数,静态函数

  2. 槽函数和信号的参数和返回值要一致

根据上面的槽特点,由于我们声明了信号 void pushButtonTextChanged(); 所以我们声明的槽函数必须是无返回值类型 void,和无需参数。所以声明槽的代码如下。此外 我们还声明一个 QPushButton 对象 pushButton。对象 pushButton 可以写成简写 btn。这个根据个 人习惯即可!简写的名称建议不要让人看不懂即可!同时还声明一个按钮点击的槽。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
/*引入 QPushButton */
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:/* 声明一个信号,只需声明,无需定义 */void pushButtonTextChanged();public slots:   /*声明一个槽函数*/void changeButtonText();/*声明按钮点击的槽函数*/void pushButtonClicked();
private:/* 声明一个对象 pushButton 也可以是btn,易于读懂就行 */QPushButton *pushButton;
private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

在 mainwindow.cpp 里实现 声 明 的 槽 函 数 void changeButtonText(); 和 void pushButtonClicked();。同时还实例化了 pushButton 对象。代码如下。

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //new一个UI中的MainWindow,这里是一种初始化成员的方法
{//ui->setupUi(this);//这句话是进行界面初始化,将this作为参数传到setupUi里,ui界面//文件的对象会以this为父对象,所有子对象将显示在MainWindow里,我们要想使用ui里的对象//必须将代码写在ui->setUi(this)这句话之后,因为ui->setupUi(this)会先初始化里面的对象,只有初始化//里面的对象我们才能使用这个对象/* 设置窗体的宽为 800,高为 480 */this->resize(800,480);/* 实例化 pushButton 对象 */pushButton = new QPushButton(this);/* 调用 setText()方法设定按钮的文本 */pushButton->setText("我是一个按钮");
}MainWindow::~MainWindow()
{delete ui;
}
/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{/* 使用 emit 发送信号 */emit pushButtonTextChanged();
}
/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{/* 在槽函数里改变按钮的文本 */pushButton->setText("被点击了!"); 
}

四. 如何在项目中连接信号与槽

信号槽连接的代码如下

connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));
connect(this,SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText()));

注意,发送信号的对象,和接收的信号的对象。因为我们 pushButtonClicked()是本类里定 义的槽,所以用 this 来接收。同理pushButtonTextChanged()也是本类定义的信号。所以发送 者写成 this。changeButtonText()也是本类的槽函数,所以接收槽的对象也是 this。

在 mainwindow.cpp 中信号槽连接的代码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //new一个UI中的MainWindow,这里是一种初始化成员的方法
{//ui->setupUi(this);//这句话是进行界面初始化,将this作为参数传到setupUi里,ui界面//文件的对象会以this为父对象,所有子对象将显示在MainWindow里,我们要想使用ui里的对象//必须将代码写在ui->setUi(this)这句话之后,因为ui->setupUi(this)会先初始化里面的对象,只有初始化//里面的对象我们才能使用这个对象/* 设置窗体的宽为 800,高为 480 */this->resize(800,480);/* 实例化 pushButton 对象 */pushButton = new QPushButton(this);/* 调用 setText()方法设定按钮的文本 */pushButton->setText("我是一个按钮");/* 信号与槽连接 */connect(pushButton, SIGNAL(clicked()), this,SLOT(pushButtonClicked()));connect(this, SIGNAL(pushButtonTextChanged()), this,SLOT(changeButtonText()));
}MainWindow::~MainWindow()
{delete ui;
}
/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{/* 使用 emit 发送信号 */emit pushButtonTextChanged();
}
/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{/* 在槽函数里改变按钮的文本 */pushButton->setText("被点击了!");
}

五. 学会使用 Qt 类的信号与槽

Qt里有大量的信号与槽,都是Qt自定义好的,那么我们该如何使用Qt信号与槽呢?

进入 QPushButton 的定义处,我们看到 QPushButton 不止 clicked 信号,还有其他信号,也 有 QPushButton 的槽函数(返回上一步按 Alt + 方向左键)。在这里我们只是简单的看了如何在 已知信号和槽里查找其他信号与槽。实际上在开发中我们经常需要使用 Qt 帮助文档来查看 Qt 定义的信号与槽。我们将在下一章里讲解 Qt 帮助文档的使用,帮助文档里面就有如何查看 Qt 的信号与槽等等。

相关文章:

Qt信号与槽

我们在使用Qt的时候&#xff0c;不使用Qt Designer 的方式进行开发&#xff0c;使用ui文件&#xff0c;信号与槽的连接方式是生成代码之后才能在setupUi函数里才能看到&#xff0c;或者需要进入Ui设计器里的信号槽模式里才能看到信号槽的连接。所以我们最好使用代码绘制界面。 …...

QQ农场-phpYeFarm添加数据教程

前置知识 plugin\qqfarm\core\data D:\study-project\testweb\upload\source\plugin\qqfarm\core\data 也就是plugin\qqfarm\core\data是一个缓存文件,如果更新农场数据后,必须要删除才可以 解决种子限制(必须要做才可以添加成功) 你不更改加入了id大于2000直接删除种子 D…...

Java中创建多线程的方法

继承Thread类&#xff0c;对该类进行new一个实例&#xff0c;对实例调用start方法&#xff0c;重写run方法。 缺点&#xff1a;单继承&#xff0c;无法继承 public class myThread extends Thread {public static void main(String[] args) {myThread myThread new myThread()…...

MT3020 任务分配

思路&#xff1a;利用二分找到某个时间是满足“k个人可以完成” &#xff0c;并且时间最小。 因为尽量让后面的人做任务&#xff0c;所以从后往前排任务&#xff08;倒着分配&#xff09;。从后往前遍历任务&#xff0c;如果此人加上这个任务超出之前求得的时间&#xff0c;就…...

【Redis】事务

Redis事务是一组命令的集合。这组命令顺序化执行而不会被其他命令插入。 Redis事务命令 命令描述DISCARD取消事务&#xff0c;放弃执行EXEC执行事务MULTI标记事务的开始UNWATCH取消WATCH对所有key的监控WATCH监控所有key Redis事务特点 特点说明单独的隔离操作Redis命令执行…...

每日一题(leetcode238):除自身以外数组的乘积--前缀和

不进阶是创建两个数组&#xff1a; class Solution { public:vector<int> productExceptSelf(vector<int>& nums) {int nnums.size();vector<int> left(n);vector<int> right(n);int mul1;for(int i0;i<n;i){mul*nums[i];left[i]mul;}mul1;for…...

内网通如何去除广告,内网通免广告生成器

公司使用内网通内部传输确实方便&#xff01;但是会有广告弹窗推送&#xff01;这个很烦恼&#xff01;那么如何去除广告呢&#xff01; 下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1CVVdWexliF3tBaFgN1W9aw?pwdhk7m 提取码&#xff1a;hk7m ID&#xff1a;…...

视频知识整理

1 视频播放器原理 视频播放器播放一个互联网上的视频文件&#xff0c;需要经过以下几个步骤&#xff1a; 解协议&#xff1a;将流媒体协议的数据&#xff0c;解析为标准的相应的封装格式数据 解封装&#xff1a;将封装格式的数据&#xff0c;分离成为音频流压缩编码数据和视…...

【2024】使用Rancher管理k8s集群和创建k8s集群

Rancher管理k8s集群及创建k8s集群。 Rancher版本为:2.8.2目录 rancher管理k8s集群rancher创建k8s集群rancher管理k8s集群 使用rancher管理已经存在的k8s集群。 本部分内容需要自行准备好k8s集群及rancher平台,部署请看本人其他文章 。 登录到rancher平台后,点击集群管理,…...

生成对抗网络 – Generative Adversarial Networks | GAN

目录 生成对抗网络 GAN 的基本原理 非大白话版本 第一阶段:固定「判别器D」,训练「生成器G」...

基于深度学习的生活垃圾智能分类系统(微信小程序+YOLOv5+训练数据集+开题报告+中期检查+论文)

摘要 本文基于Python技术&#xff0c;搭建了YOLOv5s深度学习模型&#xff0c;并基于该模型研发了微信小程序的垃圾分类应用系统。本项目的主要工作如下&#xff1a; &#xff08;1&#xff09;调研了移动端垃圾分类应用软件动态&#xff0c;并分析其优劣势&#xff1b;分析了深…...

软件包名生成参考

服务名称-分支名称-最后提交时间(精确到秒)-最后提交-编译时间(unix时间戳) 示例&#xff1a;crm_5.2_221024-221020160306-b846f829-1665655859 包名生成脚本参考&#xff1a; 分支名称 export GIT_BRANCH$(git branch|grep "\*"|head -n1|awk {print $NF})git最…...

八大排序算法(面试被问到)

1.八大排序算法都是什么&#xff1f; 八大排序算法有&#xff1a;插入排序、冒泡排序、归并排序、选择排序、快速排序、希尔排序、堆排序、基数排序&#xff08;通常不提&#xff09;。此外&#xff0c;还可以直接调用Arrays.sort()进行排序。 2.八大排序算法时间复杂度和稳定…...

SCP指令详细使用介绍

SCP&#xff08;Secure Copy Protocol&#xff09;是一种用于在计算机之间安全地传输文件的协议。它通过加密的方式在网络上安全地复制文件。SCP基于SSH&#xff08;Secure Shell&#xff09;协议&#xff0c;因此它提供了加密的连接和身份验证&#xff0c;确保数据在传输过程中…...

《前端面试题》- JS基础 - 防抖和节流

在界面触发点击&#xff0c;滚动&#xff0c;输入校验等事件时&#xff0c;如果对事件的触发频率不加以限制&#xff0c;会给浏览器增加负担&#xff0c;且对用户不友好。防抖和节流就是针对类似情况的解决方案。 防抖 防抖(debounce)&#xff1a;当连续触发事件时&#xff0…...

RAGFlow:基于OCR和文档解析的下一代 RAG 引擎

一、引言 在人工智能的浪潮中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势成为了研究和应用的热点。RAG技术通过结合大型语言模型&#xff08;LLMs&#xff09;的强大生成能力和高效的信息检索系统…...

正则表达式|*+?

在理解编程语言和编译技术的上下文中&#xff0c;了解正则表达式&#xff08;regular expressions&#xff09;和正则集&#xff08;regular sets&#xff09;的概念是非常重要的。这些概念主要用于描述一组字符串的模式&#xff0c;广泛应用于词法分析中识别各类标记&#xff…...

前端开发攻略---根据音频节奏实时绘制不断变化的波形图。深入剖析如何通过代码实现音频数据的可视化。

1、演示 2、代码分析 逐行解析 JavaScript 代码块&#xff1a; const audioEle document.querySelector(audio) const cvs document.querySelector(canvas) const ctx cvs.getContext(2d)这几行代码首先获取了 <audio> 和 <canvas> 元素的引用&#xff0c;并使用…...

【计算机毕业设计】基于Java+SSM的实战开发项目150套(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享150的Java毕业设计&#xff0c;基于ssm框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业设计和课程…...

STM32H7的MPU学习和应用示例

STM32H7的MPU学习记录 什么是MPU&#xff1f;MPU的三种内存类型内存映射MPU保护区域以及优先级 MPU的寄存器XN位AP位TEX、C、B、S位SRD 位SIZE 位CTRL 寄存器的各个位 示例总结 什么是MPU&#xff1f; MPU&#xff08;Memory Protection Unit&#xff0c;内存保护单元&#xf…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...