首页 > 其他分享 >【Qt】信号和槽

【Qt】信号和槽

时间:2024-08-24 17:51:37浏览次数:12  
标签:Widget Qt 参数 connect 信号 按钮 函数

文章目录

1. 信号和槽的基本概念

信号源:由那个控件发出的信号
信号的类型:用户进行不同的操作 就可能触发不同的信号
(点击按钮 触发点击信号)
信号的处理方式:槽 (slot) (槽相当于一个函数)

Qt中使用 connect 这样的函数 把一个信号和 一个槽 关联起来
只要信号触发 Qt就会自动执行槽函数
( 槽函数 本质是一种 回调函数 )


处理的先后顺序

回到家 你妈面色不善 你脑袋里一顿回想 是因为最近考试考的很差 所以要跟你妈表决心 一定好好学
信号源:你妈
信号类型:面色不善
信号处理方式:脑袋里一顿回想 是因为最近考试考的很差 -> 要跟你妈表决心 一定好好学


一定要把信号的处理方式准备好 再触发信号
Qt中 一定是先关联信号 和 槽 再触发信号 顺序不能颠倒 否则 信号就不知道如何处理
(你妈面色不善 你没有想到你做过什么以及解决办法 那留给你的只有一顿毒打)


connect 函数的用法

connect QObject 提供的 静态成员函数


connect 有 五个参数 但最后一个参数提供了默认参数 所以一般只考虑前四个参数
第一个参数 sender 表示信号源 描述了当前信号是那个控件发出来的
第二个参数 signal 表示信号的类型 发出哪一种信号
第三个参数 receiver 表示 那个对象负责处理
第四个参数 method 表示 这个对象该怎么处理


connect 函数 使用练习

new 一个 对象 button ( QPushButton 表示普通按钮) 其父对象为 Widget对象 (详细介绍请翻前几篇Qt博客)
使用 setText 函数 设置文本 关闭
使用 move 函数 将文本 移动


此时运行程序后 显示的关闭 按钮 按并没有反应 还需 通过 connect函数 将 信号和 槽 连接



当输入 connect 函数的 第二个参数 时 会出现 click clicked
click 为 slot (槽)函数 作用为 调用时 相当于 点击了一下按钮 (点击的动作)
clicked 为 信号函数 即 要触发的点击信号 (点击完成了)


当输入 connect 函数的 第四个参数 时
close QWidget 内置的槽函数
Widget 继承自 QWidget 也就继承了 父亲的槽函数
具体作用为 关闭当前窗口 或控件


当前信号由 button 发出 使用 clicked 触发点击信号 this作为一个指针 指向了 Widget 对象 由Widget对象负责处理
使用 close 函数 关闭当前窗口
针对 button 按钮 进行点击 Widget 就会关闭


点击 关闭按钮 当前 Widget 窗口 就会 关闭


2. 自定义 信号 和 槽

自定义槽函数

第二种定义槽函数的方式

connect 的第四个参数 作为 自定义的槽函数 handleClicked
即自己定义在Widget窗口下如何操作


槽 就是一个 普通的成员函数 即自定义槽函数 和 自定义 普通成员函数 相同
所以 在 widget.h中 添加 共有的成员函数 handleClicked


widget.cpp 中 对 自定义槽函数 handleClicked 进行定义
在Widget窗口中 若按下按钮 显示 按钮已经按下


运行程序 按下按钮后 由 Widget 变为 按钮已经按下


第二种定义槽函数的方式

打开ui界面 拖动 Push Button (普通按钮) 到右侧框中
并修改 为 按钮


此时 ui 界面 右侧的 objectName pushButton

通过 ui->pushButton 的方式 就可以获取到 界面上 拖上去的这个按钮


在ui界面上 右击按钮 选择转到槽


在对话框中 说明 QPushButton 都提供那些信号 (包含其父类的信号)


双击 clicked 就会直接生成好了 函数的声明 和 定义


运行程序后 点击按钮 依旧从 Widget 变为 按钮已经按下


在Qt中 除了通过 使用 connect 来连接 信号槽 之外 还可以通过 函数名字的方式来自动连接
on 作为前缀名字 pushButton 是 按钮的 objectName clicked 作为 信号 的名字
当函数名符合上述规则后 Qt就会自动把信号 和 槽 建立联系


自定义信号

信号对应到 用户的某个操作
Qt 信号 是一个 特殊的 函数


1. 只需写出函数声明 告诉 Qt 这是一个信号 即可
这个函数的定义 是在 Qt 编译过程中 自动生成的 (自动生成的过程 无法干预)


2.作为信号函数 这个函数的返回值 必须为 void
有没有参数都可以 也可以支持重载


signals 是 Qt自己扩展的关键字
扫描到类中包含 signals 这个关键字的时候 就会自动 把 下面的 函数声明 认为 是 信号 并且 给 这些信号函数 自动生成函数定义


mySiganl 这样的函数声明 当成信号 并且给信号自动生成对应的函数定义


声明一个槽函数 handleMySignal
并在内部使用 setWindowsTitle 设置窗口标题


this (Widget对象) 发出 mySignal 信号 再由 this (Widget对象) 通过 handleMySignal 处理


此时运行程序 发现信号并没有发出来


Qt内置的信号 不需要手动通过代码触发
用户在 GUI 进行某些操作 就会自动触发对应信号


Qt中 提供 关键字 emit (发送)
通过这样的方式 就可以把信号发射出去
此时的窗口标题 发生了改变


3. 带参数的 信号 和 槽

当信号带有参数时 槽的参数 必须和信号的参数一致
(理想情况下是这样 也可以不一样 后面会说特殊情况)

此时发射信号的时候 就可以给信号函数传递实参 与之对应的 这个参数 就会被传递到对应的槽函数中
就可以起到让信号给槽传参效果了


当写函数声明时 只需写形参的类型即可 不用写形参的名字


发送信号时 信号带有的实参会把其传递到 槽函数的形参中


运行程序后 点击按钮 发现窗口标题改变了


传参可以起到 复用代码 的效果
有多个逻辑 逻辑上基本一致 但涉及到的数据不同
就可以通过函数 来复用代码 并在不同的场景中传入不同的参数


此时只有一个connect 函数 将 信号和槽连接
同样都是 mySignal信号 但是其中内容不同

通过一套信号槽 搭配不同的参数 就可以起到设置不同标题的效果


运行程序后 若点击设置文本1为标题 则 窗口 改变为 把标题设置为标题1
若点击设置文本2为标题 则 窗口 改变为 把标题设置为标题2


参数个数的影响

信号的参数有两个 而槽的参数有一个


运行程序后 发现功能依旧正常实现

信号函数的参数个数 超过了槽函数的参数个数 都是可以正常使用的


信号参数有一个 槽函数的参数有两个


运行程序后 发现会报错

信号函数的参数个数 少于槽函数的参数个数 此时代码无法编译通过


参数类型的影响

信号的参数类型 从 const QString 变为 int


当发出信号后 将 10 和 20 传递给 text
但是由于 两者 参数类型不一致 就导致报错


4. 信号和槽存在的意义

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

一个信号 可以 connect 到多个槽函数
一个槽函数 也可以被多个信号 connect


声明三个信号 和 三个 槽函数


使用connect函数
将 mysignal1 信号 与 mySlot1 槽函数 关联
将 mysignal1 信号 与 mySlot2 槽函数 关联
将 mysignal2 信号 与 mySlot1 槽函数 关联
将 mysignal1 信号 与 mySlot1 槽函数 关联

Qt引入 信号槽机制 本质是为了能够让 信号和槽 之间按照 多对多的方式 来进行 关联
(一个信号可以关联多个槽 一个槽可以关联多个信号)


5. 信号和槽 的断开

使用 disconnect 断开 信号槽的连接


声明两个槽函数 handleClick handleClick2 并分别定义


先使用 connect 函数 将ui界面 pushButton 按钮 与 handleClick 槽函数 连接


再使用 disconnect 函数 将 pushButton 按钮 与 handleClick 槽函数 连接断开
重新使用 connect 函数 将 pushButton 按钮 与 handleClick_2 槽函数 连接


运行程序后 出现两个按钮


先点击 修改窗口标题按钮 发送信号 使得 窗口变为 修改标题


点击 切换槽函数 按钮 发送信号 使得PushButton按钮与 handleClick 槽函数 断开 与 handleClick 函数连接


再次点击 修改窗口标题按钮 此时窗口为 修改标题2

6.使用 lambda表达式 定义 槽函数

定义槽函数时 可以使用 lambda表达式

圆括号为 形参列表 大括号为 函数体内容


之前还需要在 Widget类中 写一个 槽函数的声明 再回到 Widget.cpp文件中 写一个 槽函数的定义
现在只需要 写一个 lambda 表达式 即可


由于lambda表达式 是一个 回调函数
这个函数 无法直接获取到上层作用域的变量


lambda 为了解决这个问题 引入了 变量捕获 的概念
通过变量捕获 获取到 外层 作用域中的变量

将button变量名 捕获到 lambda表达式里面 就可以正常运行了


由于 button 是 new 出来的变量 所以 生命周期 随着整个窗口(挂到对象树上 窗口关闭才会释放)


this 指向的父对象为 Widget 对象
该变量放在main函数结束后才销毁 只要进程不结束 widget就可以用 对应的this 也就 可用

lambda表达式 可以简化 槽函数的定义

标签:Widget,Qt,参数,connect,信号,按钮,函数
From: https://blog.csdn.net/qq_62939852/article/details/141461976

相关文章

  • QT-release打包程序
    QT-release打包程序哦知识阿赐予我力量活着就好​关注 QT-release打包程序主要介绍qt编写好程序后运行release生成的exe文件,之后用qt的编译程序生成qt可执行环境,之后就可以压缩打包发给用户使用!1.构建运行qt的程序​用我现在测试的demo程序为例​点击......
  • PyQt5 / PySide 2 + Pywin32 自定义标题栏窗口 + 还原 Windows 原生窗口边框特效(2)
    前言:已修复上一篇文章中提到的Bug,增加状态切换动画:PyQt5/PySide2+Pywin32自定义标题栏窗口+还原Windows原生窗口边框特效-CSDN博客https://blog.csdn.net/2402_84665876/article/details/141487635?spm=1001.2014.3001.5501仍然存在的问题:打开窗口时窗口标题栏......
  • 多媒体技术(五)之数字音频视频信号的压缩
    概述1.数字视频压缩的必要性和可能性按ITU-RBT.601建议,数字化后的输入图像格式为720*576像素,帧频为25帧/s,采样格式为4:2:2,量化精度为8bit,则数码率:(720*576+360*576+360*576)*25帧/s*8bit=165.888Mbit/s。如果视频信号数字化后直接存放在650MB的光盘......
  • PYQT5的环境配置
    一。前言系统:win11最近开始了解qt,想用qt来做一些实践项目,于是先开始了环境配置。最开始想分别配置python的环境和qt环境python环境配置简单,输入官网:python.org  找到download,在里面找到对应的python版本下载就行了,我下载的版本是3.12.5 应该是最新版本,下载完成后打开......
  • # 为什么Qt源码中要用d_ptr和q_ptr
    为什么需要d_ptr和q_ptr  Qt中的公有类中一般都会包含d_ptr这样一个私有类型的指针,指针指向该类对应的私有类,引入这个指针主要是为了解决二进制兼容的问题。q_ptr是和d_ptr配套的,后面会介绍到。什么是二进制兼容  Qt作为一个第三方库,发布后会有很多公有类提供给第三方使用......
  • 【漫谈C语言和嵌入式029】信号传输的对决:差分信号 vs. 单端信号的全面比较
            在现代电子电路和通信系统中,信号传输方式的选择对于系统性能、抗干扰能力和功耗等方面至关重要。其中,差分信号(DifferentialSignal)和单端信号(Single-EndedSignal)是两种常见的信号传输方式。它们各有优劣,适用于不同的应用场景。本文将深入探讨这两种信号传输方......
  • 【漫谈C语言和嵌入式027】探索信号处理的秘密:低通滤波器与高通滤波器的深度解析
            在嵌入式系统和数字信号处理领域,滤波器(Filter)是至关重要的工具。它们是用于处理和优化信号的基础组件,能够有效地控制信号的频率分布。滤波器的类型多种多样,其中最为基础且常用的便是低通滤波器(Low-PassFilter,LPF)和高通滤波器(High-PassFilter,HPF)。本文将......
  • Java实现MQTT通信(发布订阅消息)
    文章目录前言一、相关pom依赖二、相关代码1.MQTT工具类2.MQTT回调函数3.订阅消息4.发布消息三、安装mosquitto1.mosquitto简介2.下载四、安装MQTT.fx1.MQTT.fx简介2.下载3.使用五、java订阅消息六、java发布消息前言MQTT是一种轻量级的物联网通信协议,基于客户端-......
  • PyQt5 / PySide 2 + Pywin32 自定义标题栏窗口 + 还原 Windows 原生窗口边框特效
    Bug:当窗口不处于顶层时,如果点击窗体试图将其置于顶层,窗体自带的白边框会突然显示,最长两秒。完整性:尚未添加窗口状态的过渡动画和淡入、淡出动画。其他问题:由于Qt官方在版本6去掉了QtWin,目前暂未找到PyQt6/PySide6的解决方案。准备工作:在同目录下放四张照片:m......
  • QT中通过Tcp协议的多线程的文件传输(服务器)
    首先新建一个项目命名为SendClientSever因为要进行网络通信,在pro文件的第一行代码中添加network 一、窗口设计拖一个Widget里面放入label,lineEdit,pushbutton,名称如图修改程序设计子线程recvfile类新建一个类用来执行子线程将新建的类的头文件、recvfie.h文件和.cp......