Qt——信号和槽

一.信号和槽概述

谈及信号,很容易联想到在Linux系统中所分享到的信号。那么Linux信号和Qt信息有什么不同?

在 Qt 中,用户和控件的每次交互过程称为⼀个事件。比如 "用户点击按钮" 是⼀个事件,"用户关 闭窗口" 也是⼀个事件。每个事件都会发出⼀个信号,例如用户点击按钮会发出 "按钮被点击" 的信 号,用户关闭窗口会发出 "窗口被关闭" 的信号。

Qt信号同样包含三个要素:

  1. 由哪个控件发出。
  2. 信号的类型,如点击按钮信号,移动输入框光标信号等等。
  3. 信号的处理方式:槽(slot),即函数。

槽函数,就是对信号进行响应的函数,将信号与对应的槽函数关联之后,只要信号发出,就能执行对应的槽函数功能。


二.connect关联

在Qt中,想要将信号和槽函数关联起来,可以使用函数connect

connect(const QObject *sender,

               const char *signal,

               const QObject *receiver,

               const char *method,

               Qt::ConnectionType type = Qt::AutoConnection);

sender:信号的发送者;
signal:发送的信号(信号函数);
receiver:信号的接收者;
method:接收信号的槽函数;
type: 用于指定关联方式,默认关联方式为 Qt::AutoConnection,通常不需要手动设定。
disconnect()函数可以断开信号和槽的连接,参数与connect一致。
下面我们设计一个界面,界面上存在一个关闭按钮,点击按钮即可关闭界面:
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    QPushButton *myButten = new QPushButton(this);
    myButten->setText("关闭");
    myButten->move(200,200);
    connect(myButten,&QPushButton::clicked,this,&Widget::close);
}

分析这段代码,QPushButten为按钮类,随后为其命名为“关闭”,并设置其在界面中的位置

在connect函数中,定义的按钮myButten为信号的发送者clicked为信号函数,即“按钮被按下”这个信号this为信号的执行者,即Widget对象,也就是界面本身close为接收到信号后要执行的槽函数,即关闭界面

运行程序,点击关闭即可关闭界面。

这里扩展一点知识:

实际上上述所给出的connect函数的参数,是老版本的Qt中的connect函数,能够看到参数2和参数4,是两个char* 类型的函数指针,但实际上所传入的函数指针,并不一定都是char*类型,在老版本中,需要通过宏来修改两个参数的类型,这样太过麻烦,所以在Qt5版本之后,将connect的参数改为了模版类型,并且带有了一定的参数检查功能,即参数2和参数4必须分别是参数1和参数3两个对象的成员函数,否则就会编译出错。


三.自定义信号和槽

在上述操作中,我们所使用的信号函数和槽函数,都是对应的控件中所自带的,但是自带的这些信号和槽,肯定不能满足我们所有的需求,所以我们还需要进行自定义。


1.自定义槽函数

槽函数的本质,还是类中的一个成员函数。

(1)代码方式

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton *myButten = new QPushButton(this);
    myButten->setText("按钮");
    myButten->move(200,200);
    connect(myButten,&QPushButton::clicked,this,&Widget::handleClick);
}

void Widget::handleClick()
{
    this->setWindowTitle("按钮被按下!");
}

注意成员函数必须要在.h文件中先进行声明。

这里我们编写了一个名为handleClick的成员函数,并由connect进行连接,代码的含义为:点击按钮就会修改界面的标题为“按钮被按下!”,结果如下:


(2)界面操作

我们在界面设计中设计一个按钮,然后右键点击,能够看到一个“转为槽”的选项,点击,就能得到当前的QPushButten控件,及其父控件的所有的信号函数

我们选择clicked信号,点击OK,随后就会跳转到.cpp文件,并创建一个对应的函数,同时该函数也会在.h文件中进行声明:

随后就可以在该函数中进行代码编写:

void Widget::on_pushButton_clicked()
{
    this->setWindowTitle("按钮已经按下");
}

 运行代码,结果如下:

 能够看出,通过界面设计的槽函数,不需要使用connect函数进行连接,也可以直接实现槽函数对信号的响应

这与槽函数的名字有关,这样一个规则的名字命名方式,Qt就能自动把信号和槽函数建立联系。

on_pushButton_clicked


2.自定义信号

自定义信号比较少见,在实际开发中很少会需要自定义信号,因为在GUI中,用户能够进行的操作,是可以穷举的,Qt内置的信号,基本上已经覆盖到了所有可能得用户操作。

信号是一类非常特殊的函数,定义自定义信号函数时,我们只需给出函数声明即可信号函数的返回值必须是void,有没有参数都可以。

此时,我们需要告诉Qt,这是一个“信号”,通过在类中使用signals关键字当代码扫描到该关键字时,就会自动把下面的函数认为是信号,随后给这些函数自动生成函数定义

Qt内置的信号,都不需要我们手动通过代码来触发,那么自定义出的信号,该如何触发呢?

通过emit关键字 + 信号函数,可以触发自定义信号,当然直接调用信号函数,也可以触发信号。

signals:
    void mySignal();
public:
    void handleMySignal();

在类中声明信号。

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(this,&Widget::mySignal,this,&Widget::handleMySignal);

    emit mySignal();
    //mySignal();
}

void Widget::handleMySignal()
{
    this->setWindowTitle("触发自定义信号");
}

随后进行连接并触发信号,结果如下:


3.信号和槽传参

我们在使用信号时,也可以设置参数,当信号设置参数之后,对应连接的槽函数也必须拥有相同的类型的参数,参数的个数可以不一致,但信号的参数必须比槽函数的个数多

信号传参,本质是将参数的内容传递给槽函数,从而槽函数就可以使用参数内容:

signals:
    void mySignal(const QString& text);
public:
    void handleMySignal(const QString& text);
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(this,&Widget::mySignal,this,&Widget::handleMySignal);

    emit mySignal("信号传参");
}

void Widget::handleMySignal(const QString& text)
{
    this->setWindowTitle(text);
}

结果如下:


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx反向代理(下)

1. WebSocket的反向代理 WebSocket 是目前比较成熟的技术了, WebSocket 协议为创建客户端和服务器端需要实时双向通讯的 webapp 提供了一个选择。服务器可以向浏览器推送相关消息,这样在前端实现的某个页面中我们可以及时看到服务器的状态变化而不用使用定时刷新去…

2024年10月中国数据库排行榜:TiDB续探花,GaussDB升四强

10月中国数据库流行度排行榜如期发布,再次印证了市场分层的加速形成。国家数据库测评结果已然揭晓,本批次通过的产品数量有限,凸显了行业标准的严格与技术门槛的提升。再看排行榜,得分差距明显增大,第三名与后续竞争者…

【C++】RBTree——红黑树

文章目录 一、红黑树的概念1.1 红⿊树的规则:1.2 理解最长路径长度不超过最短路径长度的 2 倍1.3 红⿊树的效率 二、 红⿊树的实现2.1 红⿊树的结构2.2 红⿊树的插⼊2.2.1 红⿊树树插⼊⼀个值的⼤概过程 2.3 红⿊树的插⼊代码实现 一、红黑树的概念 红⿊树是⼀棵⼆…

git下载和配置

git是什么? Git是一种分布式版本控制系统,用于跟踪文件的变化,尤其是源代码。它允许多个开发者在同一项目上进行协作,同时保持代码的历史记录。Git的主要特点包括: 分布式:每个开发者都有项目的完整副本&a…

[MySQL#6] 表的CRUD (1) | Create | Retrieve(查) | where

目录 1. 插入 1.1 单行数据 - 全列插入 指定列插入 1.2 多行数据 - 全列插入 指定列插入 1.3 更新 1.4 替换 2. 查找 2.1 select 列 2.2 where 条件 具体案例 2.3 结果排序 总结关键字执行顺序 2.4 筛选分页结果 CRUD : Create(创建),Retrieve(读取)&…

C语言:代码运行的底层奥秘,编译和链接

目录 翻译环境和运行环境编译环境预编译(预处理)编译词法分析语法分析语义分析 汇编 链接运行环境 翻译环境和运行环境 在ANSI C的任何⼀种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器…

2024 FinTechathon 校园行:助力高校学生探索金融科技创新

在金融科技蓬勃发展的当下,人才培养成为推动行业前行的关键。为推进深圳市金融科技人才高地建设,向高校学子提供一个展示自身知识、能力和创意的平台,2024 FinTechathon 深圳国际金融科技大赛——西丽湖金融科技大学生挑战赛重磅开启&#xf…

第7章 内容共享

第 7 章 内容共享 bilibili学习地址 github代码地址 本章介绍Android不同应用之间共享内容的具体方式,主要包括:如何利用内容组件在应用之间共享数据,如何使用内容组件获取系统的通讯信息,如何借助文件提供器在应用之间共享文件…

控制台安全内部:创新如何塑造未来的硬件保护

在 Help Net Security 的采访中,安全研究人员 Specter 和 ChendoChap 讨论了游戏机独特的安全模型,并强调了它与其他消费设备的不同之处。 他们还分享了对游戏机安全性的进步将如何影响未来消费者和企业硬件设计的看法。 斯佩克特 (Specter) 是本周在阿…

开源项目-投票管理系统

哈喽,大家好,今天主要给大家带来一个开源项目-投票管理系统 投票管理系统主要有首页,发起投票,管理投票,参与投票,查看投票等功能 首页 为用户提供了一键导航到各个功能模块的便捷途径。 新增投票 用户…

Unity 两篇文章熟悉所有编辑器拓展关键类 (上)

本专栏基础资源来自唐老狮和siki学院,仅作学习交流使用,不作任何商业用途,吃水不忘打井人,谨遵教诲 编辑器扩展内容实在是太多太多了(本篇就有五千字) 所以分为两个篇章而且只用一些常用api举例&#xff0c…

rnn/lstm

tip:本人比较小白,看到july大佬的文章受益匪浅,现在其文章基础上加上自己的归纳、理解,以及gpt的答疑,如果有侵权会删。 july大佬文章来源:如何从RNN起步,一步一步通俗理解LSTM_rnn lstm-CSDN博…

【Docker大揭秘】

Docker 调试一天的血与泪的教训:设备条件:对应的build preparation相应的报错以及修改 作为记录 构建FASTLIO2启动docker获取镜像列出镜像运行containerdocker中实现宿主机与container中的文件互传 调试一天的血与泪的教训: 在DOCKER中跑通F…

APISQL企业版离线部署教程

针对政务、国企、医院、军工等内网物理隔离的客户,有时需要多次摆渡才能到达要安装软件的服务器。本教程将指导您使用Linux和Docker Compose编排服务,实现APISQL的离线部署。 准备 准备一台Linux(x86_64)服务器。 安装Docker Engine(推荐版本…

音视频入门基础:AAC专题(11)——AudioSpecificConfig简介

音视频入门基础:AAC专题系列文章: 音视频入门基础:AAC专题(1)——AAC官方文档下载 音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件 音视频入门基础:AAC…

docker 可用镜像服务地址(2024.10.25亲测可用)

1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因:镜像服务器地址不可用。 2.可用地址 编辑daemon.json: vi /etc/docker/daemon.json内容修改如下: {"registry-mirrors": ["https://…

【AI应用落地实战】智能文档处理本地部署——可视化文档解析前端TextIn ParseX实践

湘江之畔,秋风送爽。前不久,2024长沙中国1024程序员节在长沙盛大举行。今年的程序员节主题为“智能应用新生态”,以科技为纽带,搭建起了一个共筑智能应用新生态的交流平台,众多技术大咖齐聚一堂,探讨智能应…

echarts实现 水库高程模拟图表

需求背景解决思路解决效果index.vue 需求背景 需要做一个水库高程模拟的图表&#xff0c;x轴是水平距离&#xff0c;y轴是高程&#xff0c;需要模拟改水库的形状 echarts 图表集链接 解决思路 配合ui切图&#xff0c;模拟水库形状 解决效果 index.vue <!--/*** author:…

Kubeadm搭建k8s

一、架构 节点名称规格IP地址安装组件master012C/4G&#xff0c;cpu核心数要求大于2192.168.88.76docker、kubeadm、kubelet、kubectl、flannelnode012C/2G192.168.88.20docker、kubeadm、kubelet、kubectl、flannelnode022C/2G192.168.88.21docker、kubeadm、kubelet、kubect…

transformers和bert实现微博情感分类模型提升

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【LSTM模型实现光伏发电功率的预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模…