Qt信号和槽【1】

news2024/12/23 13:18:47

文章目录

    • 信号和槽概念
    • connect函数
    • 自定义信号和槽
      • 自定义槽
      • 自定义信号

信号和槽概念

在Linux当中有信号signal,是系统内部的通知机制,也可以认为是进程的通知机制。这里需要注意三要素:

  1. 信号源:谁发的信号
  2. 信号的类型:哪种类型的信号
  3. 信号的处理方式:注册信号处理函数,信号触发的时候,自动调用

Qt里的信号虽然和Linux的信号没有什么联系,但是有些相似之处。

Qt中的信号,也涉及要素:

  1. 信号源:哪个控件发的信号
  2. 信号的类型:当前信号是哪种信号,用户进行不同的操作,触发不同的信号
  3. 信号的处理方式:槽(slot),其实就是一个函数。使用connect这样的函数,将信号和槽关联起来,后续只要信号触发了,就会执行槽函数。所谓的槽函数,本质上也是一种“回调函数”

Qt中,一定是要先将信号和槽进行关联,然后再触发,这个顺序不能颠倒,否则信号触发的时候,不知道怎么处理了

connect函数

这个connect函数和Linux TCP socket中建立的函数,没有任何关系,只是名字一样而已

connectQObject中提供的静态成员函数

Qt中提供的这些类,本身存在一定的继承关系,QObject是Qt内置类的“祖宗类”,而connectQObject的静态成员函数,则许多类,都可以直接调用connect

connect函数原型(老版本):

connect(const QObject *sender,
        const char *signal,
        const QObject *receiver,
        const char *method,
        Qt::ConnectionType type)
  • sender:描述当前信号是哪个控件发出的(信号源)
  • signal:发出的哪种信号(信号类型)
  • receivermethod:信号如何处理
    receiver描述哪个对象进行处理
    method怎么处理(要处理信号的对象提供的成员函数)
  • type:指定关联的方式,默认方式为Qt::AutoConnection,通常不需要手动设定

connect要求信号源和信号类型这两参数类型匹配,比如说信号源类型是QPushButton,那么信号类型必须是QPushButton内置的信号,不能是其他的类

代码示例:

界面包含一个按钮,如果用户点击按钮,则关闭窗口

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>


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

    QPushButton *button = new QPushButton(this);
    button->setText("关闭");
    button->move(200, 300);
    connect(button, &QPushButton::clicked, this, &Widget::close);
}

Widget::~Widget()
{
    delete ui;
}

image-20240903210428339

closeQWidget内置槽函数,Widget继承QWidget,也就继承了父亲的槽函数

类似clicked信号,close槽这些函数,可以查阅文档:

image-20240903211515996

connect第二个和第四个参数是char*类型的,而我们传的是&QPushButton::clicked&Widget::close函数指针

image-20240903212839947

这两个形参类型是函数指针,而且还都不是char(*)(),这在C++显然是不行的

这其实是老版本的函数声明,以前给信号传参需要搭配SIGNAL宏,给槽传参数搭配SLOT宏,它们会将传入的函数指针,转成char*

connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::close));

在Qt5中,对上述写法做出简化,不需要写SIGNALSLOT了,给connect提供了重载的版本,重载版本中,第二个和第四个参数成了泛型参数,运行传入任意的函数指针

image-20240903215604114

此时如果传入的第一次参数和第二个参数不匹配,或者第三个和第四个参数不匹配,代码直接编译出错,这样就检查更加严格了

自定义信号和槽

自定义槽

所谓的slot,其实就是一个普通的成员函数;那么所谓的自定义槽函数,其实就是定义一个普通的成员函数

image-20240903221121482

在以前的Qt版本中,槽函数必须放到当中

public/ private/ protected slots:

此处的slot这是Qt拓展出的关键字,不属于C++的标准语法

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    QPushButton *button = new QPushButton(this);
    button->setText("按钮");
    button->move(200,200);
    
    //链接信号和槽
    connect(button, &QPushButton::clicked, this, &Widget::handleClicked);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handleClicked()
{
    //按下按钮, 修改窗口标题
    this->setWindowTitle("按钮点击完毕");
}

上面是通过代码方式创建的,还能通过图形化界面的方式创建

image-20240903223127194

创建之后,函数的定义和声明就自动写好了,在定义里面就可以写我们自己的槽函数了

image-20240903223625741

这里有一点,信号和槽并未conncetwidget.hwidget.cpp没有,编译生成之后的ui_widget.h也没有

这是因为Qt当中除了通过connect连接信号槽之外,还可以通过函数名字的方式来自动连接

image-20240903224046155

这些函数名符合上述规则之后,Qt会自动把信号和槽建立连接

编译的时候,会自动调用这个函数,然后触发自动连接规则

image-20240903224305210

如果是代码方式创建控件,建议手动connect

如果是图形化方式,建议采用自动的

自定义信号

自定义信号比较少见,因为信号对于用户的操作,用户的操作是可以穷举的

Qt内置的信号,基本覆盖了所有可能的用户操作


Qt的信号,本质上也是“函数”,但是信号比较特殊:

  1. 程序员只需要写出函数声明,告诉Qt这是一个信号即可;这个函数的定义是在编译的时候自动生成的(自动生成的过程,无法干预)
  2. 作为信号函数,返回值必须是void,有没有参数都行,也支持重载

image-20240903225522265

在头文件当中使用signals关键字,这个关键字是Qt自己拓展的,qmake的时候,会调用一些代码的分析和生成工具,扫描signals的时候,就会把下面的函数声明认为是信号,并且给函数自动生成定义。

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //进行连接
    connect(this, &Widget::mySignal, this, &Widget::handleMySignal);
}

Widget::~Widget()
{
    delete ui;
}

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

运行之后,发现槽函数并未执行到,标题没有改变

image-20240903225846610

这是因为目前只建立了连接,不代表信号发了出来。

如何触发信号?

Qt内置的信号,都不需要手动提供代码触发。用户在GUI进行某些操作的时候,就会触发对应信号(发射信号的代码内置到了Qt框架当中)

Qt提供了emit关键字可以触发信号,这个也是Qt自己拓展的关键字

emit mySignal();

image-20240903230238910

这个可以在任意合适的代码中触发,不一定要在构造函数当中:

GIF 2024-9-3 23-06-07

Tips:

在Qt5中,emit其实什么也没做了,真正的操作都包含在mySignal内部生成的函数定义了,就算不写,其实也可以发送,但是在实际当中,还是建议加上,这样可读性更高,表明是自定义发射的信号

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

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

相关文章

耗时一个月,我做了一个网页视频编辑器

最近又肝了一个多月&#xff0c;终于把这个网页视频编辑器做好了&#xff0c;下面我来简单介绍一下如何使用 注意目前该功能还处在测试阶段&#xff0c;可能会有很多问题&#xff0c;后续我会不断修复 体验地址 app.zyjj.cc 界面介绍 整个剪辑界面包括4个区&#xff0c;左边是…

Java毕业设计选题推荐之基于SpringBoot+Vue的校园互助帮平台【提供源码+答辩PPT+参考文档+项目部署】

&#x1f6a9;如何选题&#xff1f; 如何选题、让题目的难度在可控范围&#xff0c;以及如何在选题过程以及整个毕设过程中如何与老师沟通&#xff0c;这些问题是需要大家在选题前需要考虑的&#xff0c;具体的方法我会在文末详细为你解答。 &#x1f6ad;如何快速熟悉一个项目…

Ubuntu 下载软件包时,提示 但是它将不会被安装E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

解决办法&#xff1a; 打开 软件和更新 先更新一下&#xff1a; sudo apt-get update 接下来再次安装你需要的软件包&#xff0c;例如&#xff1a; sudo apt install libsdl2-dev

C++奇迹之旅:快速上手Priority_queue的使用与模拟实现

文章目录 &#x1f4dd;priority_queue的介绍和使用&#x1f320; priority_queue的介绍&#x1f309;priority_queue的使用 &#x1f320;仿函数的使用&#x1f320;C语言有趣的模仿push_back&#x1f320;priority_queue的模拟实现&#x1f6a9;总结 &#x1f4dd;priority_q…

小型企业如何利用人工智能的生产力

尽管生产力低下是一个长期存在的问题&#xff0c;但最近严峻的经济逆风加剧了这一问题&#xff0c;企业清算数量同比增长了 19&#xff05;。 Xero 的报告《小企业生产力&#xff1a;趋势、影响和战略》反映了这些宏观经济变化&#xff0c;显示 2023 年新西兰小企业生产力与 …

水平仪激光模组热了就不亮了怎么维修?

在建筑施工、装修设计或是精密测量等领域&#xff0c;水平仪作为不可或缺的工具&#xff0c;其准确性和稳定性直接关乎到工作的质量与效率。然而&#xff0c;许多用户在使用过程中会遇到这样一个问题&#xff1a;水平仪的激光模组在长时间使用或环境温度升高后&#xff0c;突然…

模拟实现通用型排序

本期介绍&#x1f356; 主要介绍&#xff1a;什么是泛型排序&#xff0c;即&#xff1a;无类型排序&#xff0c;以及库函数qsort()的使用&#xff0c;以及如何自己模拟实现一个泛型的冒泡排序。 文章目录 1. 什么是通用型排序2. 库函数qsort()2.1 定义2.2 使用 3. 模拟实现通用…

828华为云征文|部署多媒体流媒体平台 Plex

828华为云征文&#xff5c;部署多媒体流媒体平台 Plex 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 性能模式1.3 计费模式 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Plex3.1 Plex 介绍3.2 Docker 环境搭建3.3 Plex 部署3.4 Plex 使…

Apple M3编译OpenSSL安卓平台SO库

1.下载OpenSSL源码: https://github.com/openssl/openssl.git 2.配置NDK环境变量:vim ~/.zprofile 添加ANDROID_NDK_ROOT环境变量,iosdev改为你自己的用户名 export ANDROID_NDK_ROOT=/Users/iosdev/Library/Android/sdk/ndk/23.1.7779620 添加NDK下可执行文件路径到PATH环…

Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)

导航&#xff1a; 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码解析 推荐视频&#xff1a; 黑马程序员全套Java教程_哔哩哔哩 尚硅谷Java入门视频教程_哔哩哔哩 推荐书籍&#xff1a; 《Ja…

ubuntu2204安装kvm

ubuntu2204安装kvm 前言一、检测硬件是否支持二、安装软件三、创建/管理虚拟机1、创建存储池2、qemu创建镜像3、xml文件运行虚拟机1、范文2、xml文件创建虚机3、创建虚机 4、克隆虚机5、创建快照6、脚本创建VNC连接 四、创建集群1、安装glusterfs2、加入集群删除节点 3、 创建卷…

EasyExcel 动态表头+表头合并

EasyExcel 动态表头表头合并 ​ 最终呈现效果&#xff1a; ​ 以前对EasyExcel的使用都是一个实体类字段对应一列&#xff0c;通过以下来一一对应即可。 ExcelProperty(index 0,value "姓名" ) private String xm;​ 所以此中出现的两个问题&#xff1a; 表头合并…

【LeetCode每日一题】——LCR 168.丑数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目注意】六【题目示例】七【题目提示】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 优先队列 二【题目难度】 中等 三【题目编号】 LCR 168.丑数 四【题目描述…

多输入多输出 | Matlab实现SO-BP蛇群算法优化BP神经网络多输入多输出预测

多输入多输出 | Matlab实现SO-BP蛇群算法优化BP神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现SO-BP蛇群算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现SO-BP蛇群算法优化BP神经网络多输…

1688竞品分析这样做,超越电商同行,流量想不爆都难!

竞品分析最大的意义就是知己知彼&#xff01;清楚自己所在的位置&#xff0c;取长补短&#xff0c;确定下一阶段打法和方向。那么该怎么做竞品分析&#xff1f; 我们利用店雷达1688工具进行实操讲解&#xff0c;分别从竞品目标、价格机制、流量结构&#xff0c;3个方面教你迅速…

uniapp 做一个查看图片的组件,图片可缩放移动

因为是手机端&#xff0c;所以需要触摸可移动&#xff0c;双指放大缩小。 首先在components里建个组件 查看图片使用 uni-popup 弹窗 要注意 transform的translate和scale属性在同一标签上不会一起生效 移动就根据触摸效果进行偏移图片 缩放就根据双指距离的变大变小进行缩…

前端练习小项目 —— 养一只电子蜘蛛

前言&#xff1a;在学习完JavaScript之后&#xff0c;我们就可以使用JavaScript来实现一下好玩的效果了&#xff0c;本篇文章讲解的是如何纯使用JavaScript来实现一个网页中的电子蜘蛛。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-C…

2.3.1 协程设计原理与汇编实现coroutine

LINUX 精通 7 day23 20240908 晚19&#xff1a;25 - 21:30 课程链接地址 2.3.1 协程设计原理与汇编实现coroutine 目的 协程不是某种语言特有的&#xff0c;lua&#xff0c;go都有 ntyco 是king老师自己写的 原语操作&#xff1a;“原语操作”通常指的是在编程或计算机科学中…

Android 12系统源码_窗口管理(八)WindowConfiguration的作用

前言 在Android系统中WindowConfiguration这个类用于管理与窗口相关的设置&#xff0c;该类存储了当前窗口的显示区域、屏幕的旋转方向、窗口模式等参数&#xff0c;应用程序通过该类提供的信息可以更好的适配不同的屏幕布局和窗口环境&#xff0c;以提高用户体验。 一、类定…

性能测试的复习2-jmeter的搭建、使用、参数化

通过网盘分享的文件&#xff1a;性能测试共享文件 链接: https://pan.baidu.com/s/1A4Nc8C5Xp6qxQ5QFtecK8g?pwds73c 提取码: s73c 1、性能测试工具 2、jmeter环境搭建 3、jmeter的基本使用 4、jmeter的参数化