QT基础二、信号和槽
一、什么是信号和槽?
1、简述
在Qt框架中,信号和槽(Signals and Slots) 是一种用于对象间通信的机制。它是一种非常强大且灵活的设计模式,广泛应用于事件驱动编程中。信号和槽机制允许对象之间以松耦合的方式进行交互,而不需要直接调用彼此的方法。
2、核心概念
-
信号(Signal):
- 信号是当某个特定事件发生时发出的通知。例如,按钮被点击、滑块值改变等。
- 信号本身不执行任何操作,它只是通知其他对象发生了某些事情。
-
槽(Slot):
- 槽是一个普通的成员函数,可以像普通函数一样被调用。
- 槽的主要作用是响应信号,并执行相应的逻辑。
-
连接(Connection):
- 信号和槽通过
QObject::connect函数建立连接。 - 当信号被触发时,与之连接的槽函数会被自动调用。
- 信号和槽通过
3、工作原理
信号和槽机制的核心思想是基于回调机制,但比传统的回调更安全和灵活。以下是其工作流程:
-
定义信号和槽:
- 在类中使用
signals关键字声明信号。 - 使用
slots关键字声明槽函数。
- 在类中使用
-
建立连接:
- 使用
QObject::connect将信号与槽绑定在一起。
- 使用
-
触发信号:
- 当某个事件发生时,信号会被发射(emit)。
- 连接的槽函数会自动被调用。

4、既然信号和槽机制的核心思想是基于回调机制,为什么不直接使用 C/C++的回调函数,而去使用信号槽?
5、信号和槽的特点
-
类型安全:
- Qt 的信号和槽机制是类型安全的。如果信号和槽的参数类型不匹配,编译器会报错。
-
松耦合:
- 信号和槽机制使得对象之间的依赖关系最小化。发送信号的对象不需要知道接收信号的对象是谁。
-
多对多连接:
- 一个信号可以连接到多个槽,多个信号也可以连接到同一个槽。
6、信号槽的缺点
1. 使用信号槽,比使用回调函数,运送速度慢:
2.使用回调函数,都是同步方式执行的。
二、信号和槽的关联(手动)
1、打开上一期的代码,在ui图搜索scroll(滚动条)

2、将垂直滚动条Vertical Scroll Bar拖动至合适位置
取一个name
Vertical Scroll Bar ---> scrollBar
3、mainwindow.cpp的代码:
// MainWindow 构造函数定义
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) // 调用父类构造函数,将 parent 传递给 QMainWindow 的构造函数, ui(new Ui::MainWindow) // 初始化 ui 成员变量,创建一个 Ui::MainWindow 对象
{ui->setupUi(this);// 设置窗口标题为 "欢迎来到召唤师峡谷"setWindowTitle("欢迎来到召唤师峡谷");// 使用信号和槽机制连接滚动条 (QScrollBar) 和数字显示框 (QSpinBox 或 QLCDNumber)// 当滚动条的值发生变化时,将新的值传递给数字显示框进行更新connect(ui->scrollBar, // 滚动条对象SIGNAL(valueChanged(int)), // 滚动条的 valueChanged 信号(当滚动条值变化时触发)ui->age, // 数字显示框对象SLOT(setNum(int))); // 数字显示框的 setNum 槽函数(用于设置显示的数字)
}
运行结果:
拖动滚动条,age会被改变

三、信号和槽的关联(自动)
1、添加一个label和line edit
label ---> textLabel
line edit ---> textEdit

2、右击文本框,点击转到槽,点击textChanged

3、在生成的函数写这段代码
// 定义一个槽函数,当 textEdit 的内容发生变化时触发
void MainWindow::on_textEdit_textChanged(const QString &arg1)
{// 将 textEdit 的内容(通过参数 arg1 传递)设置为 textLabel 的显示文本ui->textLabel->setText(arg1);
}
4、运行结果
textLabel的内容会随着textEdit的内容变化而变化

注:能自动关联就尽量自动关联,一般来说,自己写的类只能手动关联
四、自定义信号和槽
1、定义信号和槽的基本规则
-
信号(Signal):
- 使用
signals关键字声明。 - 信号没有函数体,只需声明函数签名。
- 信号通过
emit关键字触发。
- 使用
-
槽(Slot):
- 使用
slots关键字声明(在 Qt 5 及以上版本中,普通成员函数也可以作为槽)。 - 槽函数可以有函数体,像普通成员函数一样实现逻辑。
- 使用
-
连接信号和槽:
- 使用
QObject::connect函数将信号与槽绑定
- 使用
2、添加一个MyClass类
注:开发中不会让信号和槽出现在同一个类,以下都是演示效果

3、在MyClass.h写入一下代码
#ifndef MYCLASS_H
#define MYCLASS_H#include <QApplication>
#include <QObject>
#include <QDebug>// 自定义类,继承自 QObject
class MyClass : public QObject {Q_OBJECT // 必须包含此宏,用于启用元对象系统public:MyClass(QObject *parent = nullptr) : QObject(parent) {}// 定义一个槽函数void mySlot(const QString &message) {qDebug() << "接收到消息:" << message;}signals:// 定义一个信号void mySignal(const QString &message);public:// 触发信号的函数void doSomething() {QString message = "Hello, World!";emit mySignal(message); // 使用 emit 关键字发射信号}};#endif // MYCLASS_H
4、在main.cpp添加一下代码
#include "mainwindow.h"
#include "myclass.h"
#include <QApplication>void test() //测试用的函数
{// 创建两个对象MyClass sender; // 发送信号的对象MyClass receiver; // 接收信号的对象// 连接信号和槽QObject::connect(&sender,&MyClass::mySignal,&receiver,&MyClass::mySlot);// 触发信号sender.doSomething();
}int main(int argc, char *argv[])
{QApplication a(argc, argv);test();//MainWindow w;//w.show();return a.exec();
}
5、运行结果

五、信号和槽的连接方式
1、自动连接(默认方式)
- 特点:
- 如果信号和槽在同一线程中,使用直接连接(
Qt::DirectConnection)。 - 如果信号和槽在不同线程中,使用队列连接(
Qt::QueuedConnection)。
- 如果信号和槽在同一线程中,使用直接连接(
- 适用场景:
- 默认情况下,
QObject::connect使用自动连接方式。
- 默认情况下,
QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot);
2、 直接连接(Qt::DirectConnection)
- 特点:
- 槽函数在信号发出的线程中立即执行。
- 适用于同一线程中的对象通信。
- 适用场景:
- 当需要快速响应信号时。
QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::DirectConnection);
3、队列连接(Qt::QueuedConnection)
- 特点:
- 槽函数在接收者的线程中异步执行。
- 适用于跨线程通信。
- 适用场景:
- 当信号发出者和接收者位于不同的线程时。
QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::QueuedConnection);
4、阻塞队列连接(Qt::BlockingQueuedConnection)
- 特点:
- 类似于队列连接,但会阻塞信号发出的线程,直到槽函数执行完成。
- 仅适用于跨线程通信。
- 适用场景:
- 当需要确保槽函数执行完成后再继续信号发出者的逻辑时。
- 注意:
- 如果信号发出者和接收者在同一线程中使用此连接方式,会导致死锁。
QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::BlockingQueuedConnection);
5、独占连接(Qt::UniqueConnection)
- 特点:
- 确保同一个信号和槽只能连接一次。
- 如果尝试重复连接,
QObject::connect会返回false。
- 适用场景:
- 当需要避免重复连接时。
bool success = QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::ConnectionType(Qt::AutoConnection|Qt::UniqueConnection));
if (!success) {qDebug() << "连接失败:信号和槽已存在连接。";
}
相关文章:
QT基础二、信号和槽
一、什么是信号和槽? 1、简述 在Qt框架中,信号和槽(Signals and Slots) 是一种用于对象间通信的机制。它是一种非常强大且灵活的设计模式,广泛应用于事件驱动编程中。信号和槽机制允许对象之间以松耦合的方式进行交互…...
MongoDB between ... and ... 操作
个人博客地址:MongoDB between ... and ... 操作 | 一张假钞的真实世界 MongoDB中类似SQL的between and操作可以采用如下语法: db.collection.find( { field: { $gt: value1, $lt: value2 } } );...
C++虚函数:解锁多态的“动态密码
C虚函数:解锁多态的“动态密码” 开篇小故事:遥控器的“智能按钮” 假设你有一个万能遥控器,上面只有一个“开关”按钮: 按下时,电视会开机,空调会制冷,电灯会亮起。同一个按钮,却…...
【深度学习】计算机视觉(CV)-目标检测-Faster R-CNN —— 高精度目标检测算法
1.什么是 Faster R-CNN? Faster R-CNN(Region-based Convolutional Neural Network) 是 目标检测(Object Detection) 领域的一种 双阶段(Two-Stage) 深度学习方法,由 Ross Girshick…...
Blazor-父子组件传递任意参数
在我们从父组件传参数给子组件时,可以通过子组件定义的[Parameter]特性的公开属性进行传值,但是当我们需要传递多个值的时候,就需要通过[Parameter]特性定义多个属性,有没有更简便的方式? 我们可以使用定义 IDictionar…...
【原创】vue-element-admin-plus完成编辑页面中嵌套列表功能
前言 vue-element-admin-plus对于复杂业务的支持程度确实不怎么样,我这里就遇到了编辑页面中还要嵌套列表的真实案例,比如字典,主字典嵌套子信息,类似于一个树状结构。目前vue-element-admin-plus给出的例子是无法满足这个需求的…...
【深度学习】计算机视觉(CV)-目标检测-DETR(DEtection TRansformer)—— 基于 Transformer 的端到端目标检测
1.什么是 DETR? DETR(DEtection TRansformer) 是 Facebook AI(FAIR)于 2020 年提出的 端到端目标检测算法,它基于 Transformer 架构,消除了 Faster R-CNN、YOLO 等方法中的 候选框(…...
DeepSeek教unity------MessagePack-02
内置支持类型: 对象序列化 MessagePack for C# 可以序列化你自己定义的公共类或结构体类型。默认情况下,可序列化的类型必须用 [MessagePackObject] 属性进行注解,成员需要用 [Key] 属性进行注解。键可以是索引(整数)…...
【达梦数据库】disql工具参数绑定
前言 在达梦数据库的使用过程中尽管管理工具很好用,但是命令行工具还是有着得天独厚的优势,但是在参数绑定方面就没有管理工具做的更加完美,现在就汇总下disql 工具参数绑定的常用几种方式 disql 参数绑定 使用 ? select * from v$dm_in…...
H5应用抓包及调试技巧
由于图片和格式解析问题,可前往 阅读原文 在现代移动互联网时代,H5 应用以其跨平台、轻量化、快速迭代的特性,成为移动开发的重要一环。然而,随着功能的复杂化和用户体验要求的提升,H5应用的调试也面临着诸多挑战&…...
Django后台新建管理员
在 Django 中,新建管理员用户通常涉及使用 Django 自带的命令行工具 manage.py。以下是具体步骤: 前提条件 Django 项目已创建:确保你已经创建了一个 Django 项目和应用。数据库已迁移:确保你已经运行了 python manage.py migra…...
输入网址到网页显示,发生了什么?
从今天起,我准备在网上输出自己的八股了 浏览器解析URL: 根据URL解析 请求协议(http),请求的服务器(www.baidu.com),请求的文件路径(可以省略),解…...
Coredump-N:sprintf写越界
最近遇到一个sanitizer检查出来的问题; unsigned long abc = 0xffffffffffffffff; char link[8] = {0}; sprintf(link, "%u", abc);这段代码存在潜在问题。 数据类型不匹配: abc 是一个 unsigned long 类型...
自学Java-面向对象高级(final、单例类、枚举类、抽象类、接口)
自学Java-面向对象高级(final、单例类、枚举类、抽象类、接口) 一、final关键字1、认识final关键字2、final修饰变量的注意3、常量 二、单例类(设计模式)1、设计模式的概念2、单例设计模式3、单例类有很多形式4、懒汉式单例类5、小…...
[LeetCode力扣hot100]-二叉树相关手撕题
简单 94.中序遍历 就说左子树-根-右子树顺序,之前也有二叉树相关的文章,基本上递归为主,这里用栈等方式实现下。 用到:栈 注意上面给出节点的基本结构,如左右,val指等 /*** Definition for a binary t…...
docker下部署kong+consul+konga 报错问题处理
前言: 由于在docker下部署一些项目比较特殊,特别是网络这一块,如果没有搞清楚,是很容易出问题的。 先上docker-compose 编排 这里的docker-compose for kong可以在 kong-compose 获取代码 version: 3.9x-kong-config:&kong…...
网络优化工作流程
DT路测 移动测试(Drive Test) CQT 定点测试(通信质量测试) DT 测试不能体现实际话务质量:回音、串音等网络问题不能通过 DT 测试发现,因此 CQT 拨打测试是 DT 测试很好的补充,也是目前室内外测…...
[题解]2024CCPC重庆站-小 C 的神秘图形
Sources:K - 小 C 的神秘图形Abstract:给定正整数 n ( 1 ≤ n ≤ 1 0 5 ) n(1\le n\le 10^5) n(1≤n≤105),三进制字符串 n 1 , n 2 ( ∣ n 1 ∣ ∣ n 2 ∣ n ) n_1,n_2(|n_1||n_2|n) n1,n2(∣n1∣∣n2∣n),按如下方法…...
React入门 - 0.React简介
React入门 - React简介 A Brief Introduction to React By JacksonML 1. 关于React React是一个知名的Web框架。众所周知,jQuery, Angular, Vue等框架都曾闪亮登场,并且,都仍然在全球市场占有一席之地。React这个颇有担当的新锐࿰…...
hive全量迁移脚本
#!/bin/bash #场景:数据在同一库下,并且hive是内部表(前缀的hdfs地址是相同的)#1.读取一个文件,获取表名#echo "时间$dt_jian_2-------------------------" >> /home/hadoop/qianyi_zengliang/rs.txt#…...
SpringCloud系列教程:微服务的未来(二十四)Direct交换机、Topic交换机、声明队列交换机
前言 在现代消息队列系统中,交换机是实现消息传递和路由的核心组件。本文将重点探讨三种常见的交换机类型:Direct交换机、Topic交换机和声明队列交换机。通过对这三种交换机的详细分析,我们将学习它们的工作原理、应用场景以及如何在实际项目…...
Sojson高级加密技术科普
1. 引言 什么是Sojson? Sojson是一款用于JavaScript代码加密与混淆的工具,它能够有效保护前端代码的知识产权,避免开发者的心血被随意窃取。 为什么需要代码加密? 在当今的互联网环境下,代码被轻易复制、篡改或逆向…...
mysql多主集群 galera cluster for mysql 8安装配置启动重启集群
[TOC] 一、安装mysql 1、安装 系统环境: Ubuntu 18.04 64位 MySQL 8.0.19 下载MySQL APT安装配置包 首先访问 https://dev.mysql.com/downloads/repo/apt/ 获取配置包下载地址 wget https://dev.mysql.com/get/mysql-apt-config_0.8.14-1_all.deb sudo dpkg -i mysq…...
gitte远程仓库修改后,本地没有更新,本地与远程仓库不一致
问题 :gitte远程仓库修改后,本地没有更新,本地与远程仓库不一致 现象: [cxqiZwz9fjj2ssnshikw14avaZ rpc]$ git push Username for https://gitee.com: beihangya Password for https://beihangyagitee.com: To https://gitee.c…...
个人搭建CDN加速服务 特网科技
在互联网快速发展的今天,网站的加载速度对用户体验有着至关重要的影响,传统的网页加载方式依赖于服务器的性能和网络环境,这使得某些网站的页面加载时间过长,用户体验不佳,为了解决这个问题,许多企业开始采…...
mybatis 入门案例
前言 我们清楚 mybatis 是一个持久层框架,可以非常便捷的操作数据库。如最常见的对数据进行增删改查操作。 项目准备 1 在mybatis 数据库 创建 user 用户表 并插入以下两条数据 以下是一个user.sql 脚本文件如何使用 脚本文件可以参照MySQL数据库的备份与还原_控…...
Spring Boot最新技术特性深度解析与实战应用
一、反应式编程:WebFlux与非阻塞架构 1.1 核心价值与场景 Spring Boot 2.x全面拥抱反应式编程模型,通过Spring WebFlux支持异步非阻塞的请求处理,适用于高并发、低延迟的微服务场景(如实时通信、物联网数据处理)。其基于Reactor库实现,采用事件循环模型,显著提升资源利…...
Python使用Flask结合DeepSeek开发
一、背景 我之前关于DeepSeek使用ollama部署的文章大家可以把DeepSeek大模型部署起来。那么ollama还提供了可以调用对应部署模型的API接口。我们可以基于这些接口,做自己的二次开发。使用pythonflaskollama就可以进行模型对话调用。并且前端采用SSE的技术࿰…...
前端常见面试题-2025
vue4.0 Vue.js 4.0 是在 2021 年 9 月发布。Vue.js 4.0 是 Vue.js 的一个重要版本,引入了许多新特性和改进,旨在提升开发者的体验和性能。以下是一些关键的更新和新特性: Composition API 重构:Vue 3 引入了 Composition API 作为…...
大模型开发实战篇7:语音识别-语音转文字
语音识别大模型,是人工智能领域的一项重要技术,它能够将人类的语音转换为文本。近年来,随着深度学习技术的不断发展,语音识别大模型取得了显著的进展,并在各个领域得到了广泛应用。 主流语音识别大模型 目前…...
