QT从入门到精通(二) ——信号与槽机制

Qt 的信号与槽机制(Signal and Slot)是 Qt 框架 中用于对象间通信的核心机制之一。它允许对象之间进行松耦合的事件驱动式通信,尤其适合 GUI 应用程序 中的事件处理。


1. 基本概念

信号 (Signal)

  • 当对象的状态发生变化时,它会发出一个信号
  • 信号是一种声明,不需要实现。
  • 信号不需要知道谁会接收它,也就是松耦合的设计。

槽 (Slot)

  • 槽是一个普通的函数,可以用来接收信号。
  • 当信号发出时,与之关联的槽函数将被自动调用。
  • 槽可以是成员函数、普通函数或 lambda 表达式。

连接 (Connect)

  • 信号和槽通过 QObject::connect() 进行连接。
  • 当信号发出时,Qt 会自动调用与其连接的槽。

2. 信号与槽的工作原理

Qt 的信号与槽机制基于 元对象系统(Meta-Object System),它使用以下特性:

  • Q_OBJECT 宏:类中必须包含此宏,表示该类支持信号与槽。
  • moc 工具:Qt 的元对象编译器,会处理信号与槽相关的代码。

Qt 的 事件循环 负责在对象间传递信号,确保槽在正确的上下文中执行。


3. 信号与槽的定义与使用

1) 定义一个信号与槽

要使用信号与槽,必须满足以下条件:

  • 类需要继承自 QObject
  • 在类声明中加入 Q_OBJECT 宏。
  • 使用 signals 关键字声明信号。
  • 使用 slots 关键字声明槽函数。

示例代码:

定义类:
#include <QObject>
#include <QDebug>

class MyObject : public QObject {
    Q_OBJECT

public:
    explicit MyObject(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void mySignal(int value); // 声明一个信号

public slots:
    void mySlot(int value) {  // 定义一个槽
        qDebug() << "Received signal with value:" << value;
    }
};

在这里插入图片描述

连接信号与槽:
#include <QCoreApplication>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    MyObject obj1, obj2;

    // 连接信号与槽
    QObject::connect(&obj1, &MyObject::mySignal, &obj2, &MyObject::mySlot);

    // 触发信号
    emit obj1.mySignal(42);

    return a.exec();
}

在这里插入图片描述

输出结果:

Received signal with value: 42

2) 连接方式

QObject::connect 有多种形式,支持不同的连接模式。

语法:

QObject::connect(sender, SIGNAL(signalName(params)), receiver, SLOT(slotName(params)));

现代写法(推荐): 使用函数指针和 lambda 表达式。

QObject::connect(sender, &ClassName::signalName, receiver, &ClassName::slotName);

Lambda 表达式示例:

QObject::connect(&obj1, &MyObject::mySignal, [](int value) {
    qDebug() << "Lambda slot received value:" << value;
});

3) 信号与槽的重载

如果信号或槽有多个重载版本,必须在连接时指定函数指针。

示例:

class Example : public QObject {
    Q_OBJECT
signals:
    void valueChanged(int);
    void valueChanged(double);
};

Example obj;
QObject::connect(&obj, static_cast<void (Example::*)(int)>(&Example::valueChanged), 
                 &obj, [](int value) { qDebug() << "Int version called:" << value; });

4. 信号与槽的特点

  1. 松耦合
    • 信号的发送者和槽的接收者无需了解彼此的存在。
  2. 类型安全
    • 信号与槽的参数必须匹配,否则编译器会报错。
  3. 多对多关系
    • 一个信号可以连接多个槽。
    • 多个信号可以连接到同一个槽。
  4. 线程安全
    • 跨线程连接时,信号会安全地传递到接收线程。

5. 信号与槽的连接类型

在多线程程序中,Qt 提供了不同的连接类型:

连接类型:

  1. Qt::AutoConnection(默认)

    • 如果信号和槽在同一线程中,则为直接连接
    • 如果在不同线程中,则为队列连接
  2. Qt::DirectConnection

    • 信号发出后,槽会立即执行,位于发送线程。
  3. Qt::QueuedConnection

    • 信号会进入接收线程的事件队列,由接收线程执行。
  4. Qt::BlockingQueuedConnection

    • 发送线程阻塞,直到槽函数执行完毕。仅适用于跨线程。

6. 注意事项

  1. 使用 Q_OBJECT
    • 类必须继承自 QObject,并包含 Q_OBJECT 宏,否则信号与槽不会工作。

在这里插入图片描述

  1. moc 工具的支持

    • 需要使用 Qt 的 Meta-Object Compiler (moc) 进行预处理,否则信号与槽无法解析。
  2. 参数匹配

    • 信号与槽的参数个数和类型必须兼容。信号的参数可以多于槽的参数,但前者必须兼容后者。
  3. 析构时自动断开连接

    • 当对象被销毁时,Qt 会自动断开与该对象相关的所有连接。

在这里插入图片描述

总结

Qt 的信号与槽机制是一种强大且灵活的事件处理机制,它提供了类型安全松耦合的通信方式,广泛用于 Qt 应用程序中的 组件间交互事件处理
现代 C++ 写法(函数指针和 Lambda 表达式)更加简洁和安全,推荐在新代码中使用。

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

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

相关文章

数据结构:Win32 API详解

目录 一.Win32 API的介绍 二.控制台程序(Console)与COORD 1..控制台程序(Console): 2.控制台窗口坐标COORD&#xff1a; 3.GetStdHandle函数&#xff1a; &#xff08;1&#xff09;语法&#xff1a; &#xff08;2&#xff09;参数&#xff1a; 4.GetConsoleCursorInf…

kubeadm_k8s_v1.31高可用部署教程

kubeadm_k8s_v1.31高可用部署教程 实验环境部署拓扑图**部署署架构****Load Balance****Control plane node****Worker node****资源分配&#xff08;8台虚拟机&#xff09;**集群列表 前置准备关闭swap开启ipv4转发更多设置 1、Verify the MAC address and product_uuid are u…

鸿蒙元服务项目实战:备忘录UI页面开发

前言 之前写过一篇关于元服务项目的上架流程&#xff0c;为了更好的了解及开发元服务&#xff0c;准备从0到1简单开发一个小项目&#xff0c;也希望能够帮助到刚刚介入到鸿蒙开发的同学&#xff0c;具体项目呢&#xff0c;也是十分的简单&#xff0c;就是一个小巧的备忘录项目&…

Linux-ubuntu点LED灯C语言版

​ 一&#xff0c;C语言点灯 1.寄存器配置 设置为SVC模式&#xff0c;复用寄存器设置GPIO1-IO003,设置电气属性&#xff0c;设置为输出模式。 2.软件 汇编语言对模式设置&#xff0c;并且将堆栈指针指向主程序&#xff1a; .global _start_start: /*设置为svr模式 */mrs …

SLM510A系列——24V,15到150mA单通道可调电流线性恒流LED驱动芯片

SLM510A 系列产品是单通道、高精度、可调电流线性恒流源的 LED 驱动芯片&#xff0c;在各种 LED 照明产品中非常简单易用。其在宽电压输入范围内&#xff0c;能保证极高的输出电流精度&#xff0c;从而在大面积的光源照明中&#xff0c;都能让 LED 照明亮度保持均匀一致。 由于…

【JavaEE】网络(2)

一、网络编程套接字 1.1 基础概念 【网络编程】指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff1b;当然&#xff0c;我们只要满足进程不同就行&#xff0c;所以即便是同一个主机&#xff0c;只要是不同进程&#xff0c;基于网络来传…

【Java数据类型学习——String】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 打印字符串长度的两种方法字符串String的比较1.用于比较引用的对象是否指向同一个内存地址2.用equa…

基于Spring Boot的校园部门资料管理系统

一、系统背景与目的 随着信息技术的飞速发展&#xff0c;校园信息化建设成为必然趋势。学校各部门在日常工作中积累了大量的资料&#xff0c;包括教学资料、学生档案、科研成果、行政文件等。传统的纸质资料管理方式存在效率低、易丢失、难以检索等问题&#xff0c;无法满足现…

STL 剖析

STL 六大组件 「STL 六大组件的交互关系」 Container 通过 Allocator 取得数据储存空间Algorithm 通过 Iterator 存取 Container 内容Functor 可以协助 Algorithm 完成不同的策略变化Adapter 可以修饰或套接 Functor、Iterator 配置器(allocator) 配置器&#xff1a;负责空间…

企业网络构建:如何满足业务需求与提升效率

企业组网指通过网络将企业内部的各种设备&#xff08;如电脑、打印机和服务器等&#xff09;连接起来&#xff0c;实现资源共享、信息交流与协同办公的过程。要打造一个高效的企业网络&#xff0c;需要从安全性、可靠性、稳定性和性能等多个方面进行综合考虑。以下内容将详细解…

升级thinkphp8最新版本,升级后发现版本不变

升级thinkphp8.0.3最新版本8.1.1&#xff0c;升级后发现版本不变&#xff0c; 更新TP有两个方法 1 全部更新(所有插件都一起更新) composer update 2 只更新TP框架核心 composer update topthink/framework 造成可能有两个原因&#xff0c;一是缓存问题&#xff0c;二是更新…

Cesium进阶教程——自定义图形、外观、绘图基础、现有着色器移植至Cesium、ShadowMapping、视频GIS、模型压平、卷帘

基础必看 WEBGL基础&#xff08;从渲染管线角度解读&#xff09; 参考路线 http://www.xt3d.online/tutorial/further/article.html 自定义图形 https://blog.csdn.net/m0_55049655/article/details/138908327 https://blog.csdn.net/m0_55049655/article/details/140306837 …

理解数据结构 hashtable的简易理解思路

结构图 为了方便演示&#xff0c;下图中分区算法为下标取模 private int hashFun(int id) {//使用 hash并取模return id % size;}Hashtable的结构如图所示&#xff1a;是一个数组&#xff08;元素为各个链表的表头&#xff09; 多个链表组成&#xff0c;也就是说 hashtable 结…

【YashanDB知识库】kettle同步PG至崖山提示no encryption pg_hba.conf记录

【问题分类】数据导入导出 【关键字】数据同步&#xff0c;kettle&#xff0c;数据迁移&#xff0c;pg_hba.conf 【问题描述】使用kettle同步postgresql至崖山数据库时提示以下报错信息&#xff1a; 【问题原因分析】pg_hba.conf 文件中没有正确配置允许从 IP 地址 连接到数…

记录2024-leetcode-字符串DP

10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09;

UE5制作伤害浮动数字

效果演示&#xff1a; 首先创建一个控件UI 添加画布和文本 文本设置样式 添加伤害浮动动画&#xff0c;根据自己喜好调整&#xff0c;我设置了缩放和不透明度 添加绑定 转到事件图表&#xff0c;事件构造设置动画 创建actor蓝图类 添加widget 获取位置 设置位移 创建一个被击中…

【USB-HID】“自动化键盘“

这里写目录标题 【USB-HID】"自动化键盘"1. 前言2. 框架3. 实现3.1 模拟键盘按键输入 【USB-HID】“自动化键盘” 1. 前言 最近从朋友那了解了一种"自动化键盘"&#xff0c;能够通过上位机录制按键脚本&#xff0c;然后执行脚本&#xff0c;实现物理键盘…

STM32F407ZGT6-UCOSIII笔记4:时间片轮转调度

本文学习与程序编写基于 正点原子的 STM32F1 UCOS开发手册 编写熟悉一下 UCOSIII系统的 时间片轮转调度 文章提供测试代码讲解、完整工程下载、测试效果图 目录 解决上文的卡系统问题&#xff1a; 使能时间片轮转调度&#xff1a; 任务初始化定义更改&#xff1a; 文件结构…

【Flask+OpenAI】利用Flask+OpenAI Key实现GPT4-智能AI对话接口demo - 从0到1手把手全教程(附源码)

文章目录 前言环境准备安装必要的库 生成OpenAI API代码实现详解导入必要的模块创建Flask应用实例配置OpenAI API完整代码如下&#xff08;demo源码&#xff09;代码解析 利用Postman调用接口 了解更多AI内容结尾 前言 Flask作为一个轻量级的Python Web框架&#xff0c;凭借其…

搭建springmvc项目

什么是springmvc MVC它是一种设计理念。把程序按照指定的结构来划分: Model模型 View视图 Controller控制层 springmvc框架是spring框架的一个分支。它是按照mvc架构思想设计的一款框架。 springmvc的主要作用: 接收浏览器的请求数据&#xff0c;对数据进行处理&#xff0c;…