关于QT信号、槽、槽函数的讲解
也是好久没有发帖子了,最近博主主要还是在边学QT边完成任务,所以进度很慢,但确实在这几天对于QT自身槽和信号这类特殊的机制有了一定简单的理解,所以还是想记录下来,如果有初学者看到帖子对他有一定的帮助,那自然也会让我感到十分荣幸
一. 什么是信号与槽
首先按照专业术语的描述是,QT的信号与槽机制是一种对象间通信机制。直观的可以表现出一个对象发出信号,另一个对象通过槽函数响应这个信号,从而实现多模块之间的解耦通信。这个也是属于Qt框架最强大的特性之一,也是尤其适合GUI事件响应和模块间协作。
通过举一个简单的例子,家门口有一个门铃按钮(就是等同于我们的信号),我们按了一下,屋里的电铃声就响了(槽函数)。
按门铃 = 发出信号 电铃声响了 = 槽函数被触发 按下和响铃之间 = connect()建立连接。
二. 信号/槽基本概念
信号(Signal)是QObject的子类在特定事件发生时自动发出的“通知”,就是一个事件的广播。
而槽(Slot)可以与信号连接的普通成员函数,专门用于响应通知,也就是“接收广播后做事”的函数
connect(),Qt提供的函数,用于建立信号与槽之间的绑定关系,“把信号线插进槽口”
emit,是一个关键字,用于触发自定义信号,也就是程序员手动“发出广播”
QObject,QT所有支持信号、槽的类的基类,信号槽必须用它派生出来的类
三. 广播机制
在QT的信号与槽机制种,广播机制指的是。信号一旦发出,系统会自动通知所有已连接的槽函数执行,无需显示调用,且发送者不关心接收者的存在与行为。
这种机制体现了一种松耦合、发布-订阅式的通信模型,是Qt框架中组件之间高效协作的核心基础。
解耦(Decoupling),信号发送者和接收者之间并没有直接依赖关系。发送者只负责发出信号,而不需要知道是否有接收者,更不需知道接收者是谁或要做什么。这样可以使模块之间保持独立,便于维护或拓展。
一对多连接,一个信号可以同时连接多个槽函数。当信号被发出时,所有已经连接的槽将会被系统一次调用,按连接顺序一次执行。这样可以使一个事件可以触发多个处理逻辑,从而实现模块联动
多对一连接:多个 不同的信号可以连接到同一个槽函数。当任意一个信号被发出时,该槽函数都会被执行。这使得不同来源的事件可以集中处理
自动调用:当信号发出时,所有与之连接的槽函数会被自动执行,对于我们开发者来说并不需要手动调用。Qt框架内部通过事件系统和元对象机制完成槽函数的自动触发,我们只需要专注于逻辑实现
在Qt中信号是广播式的,信号本身只是简单的发出,并没有指定特定的接收者。接收者(槽函数)会通过connect()来“订阅”这个信号。
可以理解为信号式“广播”出去的,它不会知道谁会接收到它,接收者通过connect()函数明确指定自己要接受哪个信号,所以如果没有明确指定的接收者,那么这个函数就无法触发任何行为,因为没有对象响应找个信号
在代码中可以这么理解,nullptr表示没有指定接收者,那么即使按钮被点击,信号也不会触发任何函数
// 如果没有指定接收者,信号会发出,但没有接收者来处理它
QObject::connect(&button, &QPushButton::clicked, nullptr, nullptr);
刚开始我将Qt的广播形式和网络广播的形式弄混淆了,这里还是想做一个简单的澄清,是两个不同的概念
网络广播在网络中,广播通常指的是将信息发送到网络上的所有设备,而不仅仅是发送给某一个指定的接收者。常见的网络广播是无差别地将信息发送给网络上的所有设别,而接收这些广播的设备通常是主动应答的,
例如UDP广播,数据包被发送到一个特定的广播地址(如255.255.255.255),网络上的所有设备都有机会接收到这个广播。然后,每个接收到广播信息的设备可以选择是否回应(例如一般就是发送一个响应报文)
在Qt中,信号的“广播”并不是指将消息发送给所有对象,而是一个信号可以连接到多个槽函数,因此多个接收者可以对同一个信号做出响应。信号本身并不主动去寻找接收者,而是通过connect()函数明确指定了哪些接收者应该处理这个信号
信号发出:信号并不是想网络广播那样发送给所有设备,而是只从一个对象发出。可以想像是在说“我发生了某个事件,看下是否会有人响应我”
“接收者”:只有通过connect()函数明确指定了接收者(即槽函数)后,信号才会被“接收”,并且接收者会执行相应的操作。这个过程并不需要接收者主动应答,而是由QT框架自动处理的
四. 信号与与槽的连接方式及适用场景
我们将他分为一下五种
系统信号(Qt自带) + 系统槽(如QAPPlication::quit)这种组合方式可以快速调用系统功能。
信号部分是&QPushButton::clicked,这是Qt框架内置的标准信号,属于系统控件QPushButton,当按钮被点击时自动发出。所有这是系统信号(也就是由Qt控件自带)
槽部分 &QApplication::quit,这是Qt提供的一个系统级槽函数,作用是关闭应用程序主事件循环,相当于”退出应用“所以是系统槽(由Qt提供)
#include "mainwindow.h"#include <QApplication>
#include <QPushButton>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;QPushButton button("Quit",&w);button.move(100,100);QObject::connect(&button, &QPushButton::clicked,&a,&QApplication::quit);w.show();return a.exec();
}
系统信号 + 自定义槽函数 是目前较为常见的方式,如按键触发逻辑。那么同样的代码逻辑如何在系统信号 + 自定义槽函数中体现。
在下面这段代码中系统信号自然是,Qt自带的信号,如QPushButton::clicked(),表示按钮被点击。
而自定义的槽函数,是我们写在类中的处理函数,在这里是MainWindow::onButtonClicked()
所以简单来理解“系统信号 + 自定义槽函数”就是——,按钮这种系统组件发出信号,用户自己写的函数去接收并响应
QpushButton内部有个信号:void clicked(bool checked = false);当我们用connect()把这个信号和函数onButtonClicked()连接在一起,当我们点击按钮的时候,按钮会发出clickced信号(也就是前面提到的广播机制)。Qt自动调用我们自定义的槽函数onButtonClicked来处理事件
//在MainWindow.cpp中MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QPushButton *button =new QPushButton("Quit",this);button->move(100,100);connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onButtonClicked()
{qDebug() << "按钮被点击";
}//在MainWindow.h中#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;private slots:void onButtonClicked();
};
#endif // MAINWINDOW_H
自定义信号 + 系统槽 一般适用于自定义行为影响系统行为
我们通过程序执行的顺序来理解代码,首先第一步显示从连接按钮点击信号开始,对应mainwindows.cpp,connect(),当button被点击的时候,调用MainWindow的onButtonclicked()方法。button是发出信号的对象,&QPushButton::Clicked()是系统信号(点击按钮后发出)。
但是这里就要有疑惑了,明明是使用我们的自定义信号,为什么还是是系统信号呢?先不着急我们先分析完,之后再进行解释
this是当前窗口对象(MainWindow),&Mainwindow::onButtonClicked是我们自定义的槽函数,响应按钮点击
在按钮点击过后,在void MainWindow这个我们自己编写的槽函数中,在这个函数中我们有发出了另外一个信号quitApp(),这是我们在头文件中signals:定义的自定义信号
也就是说,刚开始按钮被点击后发出系统信号,触发了我们自己的函数onButtonClicked(自定义槽),然后onButtonClicked中又调用了emit quitApp(发出我们的自定义信号)
总结一下我们代码中完成的工作是,我们点击按钮触发系统信号,然后Qt自动调用我们定义的槽函数,我们的槽函数里发出quitApp(),里面是我们自定义的信号
//在mainwindow.h#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;private slots:void onButtonClicked();//自定义信号
signals:void quitApp();};
#endif // MAINWINDOW_H//在mainwindow.cpp中#include "mainwindow.h"
#include "ui_mainwindow.h"#include "QPushButton"
#include "QDebug"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QPushButton *button =new QPushButton("Quit",this);button->move(100,100);connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);connect(this,&MainWindow::quitApp,qApp,&QApplication::quit);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onButtonClicked()
{emit quitApp();
}
现在我们来解释一下,为什么整个程序执行的流程始终是系统信号。那为什么又还要发出自定义信号,博主后面了解到,Qt设计的很巧妙的地方就在于,信号链的“解耦”和“转发”能力。
例如我们需要在点击按钮的时候退出程序,还想要加入记录日志、播放音效、保存设置等,如果全部写在onButtonclicked()里,那么这个槽函数就会越来越大,越来月耦合。
那么我们在遇到这样的情况下就可以采取,在onButtonClicked()里发出一个自定义信号quitApp(),然后让其他模块自由决定是否接收这个信号,或者怎么处理信号
例如如下情况,把“按钮点击的事件”,拆成了“点击后发出quitApp”信号,然后让其他的函数也来订阅这个信号
connect(this, &MainWindow::quitApp, qApp, &QApplication::quit); // 退出程序
connect(this, &MainWindow::quitApp, logger, &Logger::writeQuitLog); // 写日志
connect(this, &MainWindow::quitApp, soundPlayer, &Player::playExitSound); // 播放音效
我们再举一个实际的例子,如果我们把多个行为都写再onButtonClicked中
void MainWindow::onButtonClicked() {qApp->quit(); // 退出程序settingsManager->save(); // 保存设置logger->log("用户点击退出"); // 写日志soundPlayer->play("bye.wav"); // 播放音效
}
我们将所有的行为都写在了一个函数中,主窗口知道太多别的类(Logger、Player、SettingManager),如果将来我们选哟将其中的功能进行改变,要修改的地方就有很多,而且假如其他的地方也需要退出行为,还要复制代码到其他地方
// MainWindow.h
signals:void quitApp(); // ⛳️ 只发信号,不处理具体细节
void MainWindow::onButtonClicked() {emit quitApp(); // ⛳️ 你们谁爱处理谁处理,我不管
}
在程序初始化的时候就可以通过信号连接不同的行为,所以总结就是,如果在一个槽函数中做了太多和“自己职责无关的事”,就可以考虑广播事件,让其他人来听
connect(mainWindow, &MainWindow::quitApp, qApp, &QApplication::quit);
connect(mainWindow, &MainWindow::quitApp, logger, &Logger::logQuit);
connect(mainWindow, &MainWindow::quitApp, settings, &Settings::save);
connect(mainWindow, &MainWindow::quitApp, soundPlayer, &Player::playExitSound);
自定义信号 自定义槽函数 一般常用于模块解耦、自主通信,如果针对于自定义槽函数和信号,肯定会有更高的自由度,我们还是结合代码来分析
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;private slots:void onButtonClicked(); //自定义槽(用于发送信号)void handClose(); //自定义槽(响应信号关闭窗口)//自定义信号
signals:void closeApp(); //自定义信号};
#endif // MAINWINDOW_H//在mainwindow.cpp中#include "mainwindow.h"
#include "ui_mainwindow.h"#include "QPushButton"
#include "QDebug"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QPushButton *button =new QPushButton("Quit",this);button->move(100,100);connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);connect(this,&MainWindow::closeApp,this,&MainWindow::handClose);
}MainWindow::~MainWindow
()
{delete ui;
}void MainWindow::onButtonClicked()
{emit closeApp();
}void MainWindow::handClose(){qDebug() << "收到信号,关闭窗口";this->close();}
首先还是在头文件总声明一个自定义信号,以及private slots中全是自定义的槽函数,也是在头文件中声明。
然后在mainwindow中的构造函数中进行连接
,connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);
//这行是系统信号(QPushButton::clicked)
//->自定义槽(onButtonClicked)作用是:当按钮被点击,就会自动调用onButtonClicked()这个槽函数
connect(this, &MainWindow::closeApp, this, &MainWindow::handleClose);这行是自定义信号(closeApp)->自定义槽(handleClose)作用就是当你发出closeApp信号时,Qt就会自动去调用handleClose()这个函数。
然后在槽函数中发出信号,这个函数并不会直接关闭窗口。它只是发出一个“广播”,说明我准备关闭了
void MainWindow::onButtonClicked()
{emit closeApp();
}
最后在响应的槽中执行操作
void MainWindow::handleClose()
{this->close(); // 真正关闭主窗口
}
以及最后任意信号 + Lambda表达式 通常简洁高效,适合小型逻辑处理。这个机制是Qt信号槽机制中最灵活也是最现代的的用法之一,非常适合简介逻辑、快速响应、小功能点,无需定义额外的槽函数,直接在connect()中用Lambda表达式表达处理逻辑
Lambda是一种匿名函数(临时的小函数),语法如下,一般用于只想快速响应一下,并不想为了这个操作特地去写某个函数
[]() {// 执行的代码
};
例如。如果只是临时逻辑、简单调试、小按钮响应等首选Lambda,但是如果逻辑复杂、选哟复用、设计多个模块之间的通信还是尽量选择传统的槽函数。但是如果在大型的项目中涉及到多个对象协作、跨模块、需要事件驱动使用自定义信号 + 自定义槽
QPushButton *button = new QPushButton("点我", this);
button->move(100, 100);// 用 lambda 直接响应点击
connect(button, &QPushButton::clicked, [](){qDebug() << "👋 Lambda:按钮被点击啦!";
});
博主去查了一下Lambda的具体原理,它是C++ 11引入的一种匿名函数(inline function)是临时写在某个地方的小函数,不需要在别的地方声明或命名,基本语法如下
[capture](parameter_list) -> return_type {// function body
}
但大部分时候还是选择写成简略的写法
[]() {qDebug() << "Hello Lambda!";
};
相关文章:
关于QT信号、槽、槽函数的讲解
也是好久没有发帖子了,最近博主主要还是在边学QT边完成任务,所以进度很慢,但确实在这几天对于QT自身槽和信号这类特殊的机制有了一定简单的理解,所以还是想记录下来,如果有初学者看到帖子对他有一定的帮助,…...
算法训练营第三十天 | 动态规划 (三)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、01背包问题理论基础(一)动态规划五部曲确定dp数组以及下标的含义确定递推公式初始化dp数组确定遍历顺序 二、01背包问题理论基础&#…...
Vue开发网站会有“#”原因是前端路由使用了 Hash 模式
前言 网站链接中出现 #(井号)是因为你的前端路由使用了 Hash 模式(hash mode),这是一种前端框架(如 Vue.js、React 等)中常用的路由策略。 为什么有 # 比如 https://www.zimeinew.com/#/order…...
SpringBootTest报错
Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or … 解决方案:在SpringTest注解中添加属性(classes )填写启动类 如我的启动类是MainApplication.class javax.websocket.server.ServerContainer no…...
【质量管理】现代TRIZ(萃智)理论概述
一、什么是TRIZ理论 TRIZ理论,即发明问题解决理论(Teoriya Resheniya Izobreatatelskikh Zadatch),是由前苏联发明家根里奇阿奇舒勒(Genrich S. Altshuller)于1946年创立的。它是一门基于知识的、面向人的发明问题解决系统化方法学。TRIZ理论通过研究大量的专利,总结出技…...
前端面经-JS篇(四)--回调地狱、promise异步编程、Proxy 与 Reflect 、模块化
一、回调地狱 回调地狱(Callback Hell),也称为回调地狱,是指在 JavaScript 中处理多个嵌套的异步回调函数时,代码结构变得非常难以阅读和维护的现象。 为什么会出现回调地狱? 回调地狱通常出现在需要执行…...
【oql】spark thriftserver内存溢出,使用oql查询导致oom的sql
eclipse memory analyzer (mat)软件内的OQL实现查询内促信息。 帮助信息:软件Help/Help Contents/Querying Heap Objects (OQL) 就是查询SparkExecuteStatementOperation 的statement 字段。 select objects s.statement from org.apache.spark.sql.hive.thriftser…...
算法设计与分析(基础)
问题列表 一、 算法的定义与特征,算法设计的基本步骤二、 算法分析的目的是什么?如何评价算法,如何度量算法的复杂性?三、 递归算法、分治法、贪婪法、动态规划法、回溯法的基本思想方法。四、 同一个问题,如TSP&#…...
爬虫学习——使用HTTP服务代理、redis使用、通过Scrapy实现分布式爬取
一、使用HTTP服务代理 由于网络环境、网站对用户的访问速度的限制等原因,使得爬取过程会出现IP被封禁,故使用代理可提高爬取速度。在Scrapy中提供了一个HttpProxyMiddleware专门用于进行爬虫代理设置。在使用该代理进行爬取操作时,需要先在ba…...
机器学习中的特征存储是什么?我需要一个吗?
本质上,特征存储是一个专用存储库,用于系统地存储和排列特征,主要用于数据科学家训练模型,并帮助已训练模型的应用程序进行预测。它是一个关键的聚合点,人们可以在此构建或修改从各种数据源提取的特征集合。此外,它还支持从这些特征组中创建和增强新的数据集,以满足处于…...
【C语言】C语言中的联合体与枚举类型
前言 在C语言中,联合体(union)和枚举(enum)是两种非常实用但又常被忽视的自定义数据类型。它们在内存管理、代码可读性以及程序设计的灵活性方面都有着独特的优势。今天,我们就来深入探讨一下联合体和枚举…...
Golang编程拒绝类型不安全
button-chen/containertypesafe-go: 使用泛型包装标准库的容器 list、ring、heap、sync.Pool 和 sync.Map,实现类型安全 简介 在 Go 中,标准库提供了多种容器类型,如 list、ring、heap、sync.Pool 和 sync.Map。然而,这些容器默认…...
炼锌废渣提取钴工艺流程
炼锌废渣中提取钴的工艺流程通常结合湿法冶金技术,针对废渣中钴与锌、铁、铜等金属的复杂共生特性,通过预处理、浸出、除杂、钴富集及提纯等步骤实现钴的高效回收。以下是典型工艺流程的详细说明: 一、预处理 炼锌废渣(如锌浸出…...
Restful接口学习
一、为什么RESTful接口是数据开发的核心枢纽? 在数据驱动的时代,RESTful接口如同数据高速公路上的收费站,承担着数据交换的核心职责。数据工程师每天需要面对: 异构系统间的数据交互(Hadoop集群 ↔ 业务系统…...
仿真每日一练 | ABAQUS应力松弛
应力松弛是弹性材料在应力作用下产生微塑性变形,并且逐渐积累,在保持应变或者位移不变的前提下,表现为应力逐渐下降的现象。今天介绍一个ABAQUS中应力松弛的相关案例,模型如下所示: 图1 模型认识 回顾一下ABAQUS的有限…...
智能电网第4期 | 电力设备全连接组网方案:从有线到无线无缝融合
随着新型电力系统建设的加速推进,电力设备通信网络正面临前所未有的挑战与机遇。在变电站自动化、输电线路监测、配电房智能化等场景中,传统通信方案已难以满足日益增长的连接需求: 环境复杂性:变电站强电磁干扰环境下需保障微秒级…...
Python 面向对象练习
不多bb了,直接上代码吧。 from pprint import pprint class Course:total_course []def __init__(self,name,id):self.name nameself.id idself.is_select FalseCourse.total_course.append(self)def __repr__(self):return (f"{__class__.__name__}("f"学…...
无感字符编码原址转换术——系统内存(Mermaid文本图表版/DeepSeek)
安全便捷无依赖,不学就会无感觉。 笔记模板由python脚本于2025-04-24 20:00:05创建,本篇笔记适合正在研究字符串编码制式的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值:在于输出思考与经验,而不仅仅是知识的简单复述。 P…...
机器学习--线性回归模型
阅读本文之前,可以读一读下面这篇文章:终于有人把线性回归讲明白了 0、引言 线性回归作为统计学与机器学习的入门算法,以其简洁优雅的数学表达和直观的可解释性,在数据分析领域占据重要地位。这个诞生于19世纪的经典算法…...
HTML应用指南:利用GET请求获取微博签到位置信息
在当今数字化时代,社交媒体平台已成为人们日常生活中不可或缺的一部分。作为中国最受欢迎的社交平台之一,微博不仅为用户提供了一个分享信息、表达观点的空间,还通过其丰富的功能如签到服务,让用户能够记录自己生活中的点点滴滴。…...
如何检测Python项目哪些依赖库没有使用
要检测Python项目中哪些依赖库未被使用,可以采用以下方法: 1. 使用静态分析工具 vulture:静态分析工具,检测未使用的代码和导入 pip install vulture vulture your_project/pyflakes:检查未使用的导入语句 pip ins…...
数据仓库建设全解析!
目录 一、数据仓库建设的重要性 1. 整合企业数据资源 2. 支持企业决策制定 3. 提升企业竞争力 二、数据仓库建设的前期准备 1. 明确业务需求 2. 评估数据源 3. 制定项目计划 三、数据仓库建设的具体流程 1.需求分析 2.架构设计 3.数据建模 4.ETL 开发 5.…...
magic-api连接达梦数据库
引入依赖 然后手写驱动 <dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.1.193</version></dependency> jdbc:dm://127.0.0.1:5236?schemaSALES...
向量检索新选择:FastGPT + OceanBase,快速构建RAG
随着人工智能的快速发展,RAG(Retrieval-Augmented Generation,检索增强生成)技术日益受到关注。向量数据库作为 RAG 系统的核心基础设施,堪称 RAG 的“记忆中枢”,其性能直接关系到大模型生成内容的精准度与…...
WHAT - 区分 Git PR 和 MR
文章目录 PR(Pull Request)MR(Merge Request)相同点总结 git pr 和 git mr 本质上都是「合并请求」的意思,但它们对应的是不同的平台术语。 PR(Pull Request) 平台:GitHub、Bitbuc…...
Axure复选框组件的深度定制:实现自定义大小、颜色与全选功能
在产品设计中,复选框作为用户与界面交互的重要元素,其灵活性直接影响到用户体验。本文将介绍如何利用Axure RP工具,通过高级技巧实现复选框组件的自定义大小、颜色调整,以及全选功能的集成,为产品原型设计增添更多可能…...
Datawhale AI春训营——用AI帮助老人点餐
详细内容见官网链接:用AI帮助老人点餐-活动详情 | Datawhale...
两段文本比对,高亮出差异部分
用法一:computed <div class"card" v-if"showFlag"><div class"info">*红色背景为已删除内容,绿色背景为新增内容</div><el-form-item label"与上季度比对:"><div class"comp…...
uniapp 仿小红书轮播图效果
通过对小红书的轮播图分析,可得出以下总结: 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下: <template><view> <!--轮播--><s…...
审计效率升级!快速匹配Excel报表项目对应的Word附注序号
财务审计报告一般包括:封面、报告正文、财务报表(Excel工作簿)以及对应的财务报表附注(Word文档)、事务所营业执照以及注册会计师证件。 在审计报告出具阶段,为各报表项目填充对应的Word附注序号ÿ…...
Python 中 `r` 前缀:字符串处理的“防转义利器”
# Python 中 r 前缀:字符串处理的“防转义利器” 在 Python 编程过程中,处理字符串时经常会遇到反斜杠 \ 带来的转义问题,而 r 前缀的出现有效解决了这一困扰。它不仅能处理反斜杠的转义,还在多种场景下发挥着重要作用。接下来&a…...
1️⃣6️⃣three.js_光源
16、光源 3D虚拟工厂在线体验 在 Three.js 中,环境光(AmbientLight)、点光源(PointLight)、平行光(DirectionalLight)、 聚光灯(SpotLight)、半球光(Hemisph…...
AD16如何执行DRC检测
AD16如何执行DRC检测 DRC检测主要用来查看走线是否出现通断,以及是否出现短路。 1)、点击“Tools”---“Design Rule Check…” 2)、全部勾选 3)、勾选“Electrical”中的“Batch”选项,参与DRC检测 4)、勾选“Routing”中的“Batch”选项,…...
PostgreSQL性能优化实用技巧
PostgreSQL的性能优化需从索引设计、查询调优、参数配置、硬件资源等多维度入手。以下为实战中验证有效的优化策略,适用于高并发、大数据量等场 一、索引优化:精准加速查询 1.选择正确的索引类型 BRIN索引:对按时间或数值顺…...
Vue3 ref与props
ref 属性 与 props 一、核心概念对比 特性ref (标签属性)props作用对象DOM 元素/组件实例组件间数据传递数据流向父组件访问子组件/DOM父组件 → 子组件响应性直接操作对象单向数据流(只读)使用场景获取 DOM/调用子组件方法组件参数传递Vue3 变化不再自…...
SpringBoot | 构建客户树及其关联关系的设计思路和实践Demo
关注:CodingTechWork 引言 在企业级应用中,客户关系管理(CRM)是核心功能之一。客户树是一种用于表示客户之间层级关系的结构,例如企业客户与子公司、经销商与下级经销商等。本文将详细介绍如何设计客户树及其关联关系…...
SpringCloud——负载均衡
一.负载均衡 1.问题提出 上一篇文章写了服务注册和服务发现的相关内容。这里再提出一个新问题,如果我给一个服务开了多个端口,这几个端口都可以访问服务。 例如,在上一篇文章的基础上,我又新开了9091和9092端口,现在…...
Springboot3+ JDK21 升级踩坑指南
目录 GetMapping和 RequestBody 一起使用时,会把请求方式由GET变为POST 变更默认的httpClient feign 超时配置失效 GetMapping和 RequestBody 一起使用时,会把请求方式由GET变为POST 变更默认的httpClient 添加依赖 <dependency><groupId&g…...
Qt UDP组播实现与调试指南
在Qt中使用UDP组播(Multicast)可以实现高效的一对多网络通信。以下是关键步骤和示例代码: 一、UDP组播核心机制 组播地址:使用D类地址(224.0.0.0 - 239.255.255.255)TTL设置:控制数据包传播范围(默认1,同一网段)网络接口:指定发送/接收的物理接口二、发送端实现 /…...
idea连接远程服务器kafka
一、idea插件安装 首先idea插件市场搜索“kafka”进行插件安装 二、kafka链接配置 1、检查服务器kafka配置 配置链接前需要保证远程服务器的kafka配置里边有配置好服务器IP,以及开放好kafka端口9092(如果有修改 过端口的开放对应端口就好) …...
第十节:性能优化高频题-虚拟DOM与Diff算法优化
优化策略:同层比较、静态节点标记、最长递增子序列算法 Key的作用:精确识别节点身份 虚拟DOM与Diff算法深度优化策略解析 一、核心优化策略 同层比较机制 Diff算法仅对比同一层级的虚拟节点,避免跨层级遍历带来的性能损耗。 • 实现原理&am…...
vmware workstation的下载地址页面
Fusion and Workstation | VMware...
kubernetes》》k8s》》Dashboard
安装Dashboard 因为我的Kubernetes 版本是 v1.28.2 对应的 Dashboard V2.7.0 wget -O https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml # 因为默认是集群内访问的,需要追加 NodePort访问类型 vim recommended.yaml …...
软考:数值转换知识点详解
文章目录 1. 进制转换1.1 二进制(Binary)、八进制(Octal)、十进制(Decimal)、十六进制(Hexadecimal)之间的转换1.2 手动转换和计算方法1.3 使用编程语言进行进制转换 2. 数据类型转换…...
第15章:MCP服务端项目开发实战:性能优化
第15章:MCP服务端项目开发实战:性能优化 在构建和部署 MCP(Memory, Context, Planning)驱动的 AI Agent 系统时,性能和可扩展性是关键的考量因素。随着用户量、数据量和交互复杂度的增加,系统需要能够高效地处理请求,并能够平滑地扩展以应对更高的负载。本章将探讨 MCP…...
Windows申请苹果开发者测试证书Uniapp使用
注意事项 苹果设备,最好是iPhone XS以上,要不然下载不了Apple DeveloperopenSSL 要是V1版本的来生成证书,要不然HBuilder报错按步骤来,生成证书,生成标识符,添加测试设备,生成描述性文件注册苹果开发者账号 (如果有苹果账号直接登录) 苹果开发者官网 开通付费 点击右上…...
服务器数据恢复—NAS存储中raid5上层lv分区数据恢复案例
NAS数据恢复环境: QNAP TS-532X NAS设备中有两块1T的SSD固态硬盘和3块5T的机械硬盘。三块机械硬盘组建了一组RAID5阵列,两块固态硬盘组建RAID1阵列。划分了一个存储池,并通过精简LVM划分了7个lv。 NAS故障: 硬盘故障导致无法正常…...
uniapp跨平台开发---switchTab:fail page `/undefined` is not found
问题描述 在项目中新增了一个底部tab导航栏,点击底部tabBar,跳转失败,控制台打印错误信息switchTab:fail page /undefined is not found 排查思路 错误信息提示,switchTab跳转的页面路径变成了/undefined,排查新增的pages.json文件,发现pages,以及tabBar中的list均已经加入该导…...
详细讲解 QMutex 线程锁和 QMutexLocker 自动锁的区别
详细讲解 QMutex 线程锁和 QMutexLocker 自动锁的区别 下面我们详细拆解 Qt 中用于线程同步的两个核心类:QMutex 和 QMutexLocker。 🧱 一、什么是 QMutex? QMutex 是 Qt 中的互斥锁(mutex)类,用于防止多个…...
如何获取静态IP地址?完整教程
静态IP地址,因其固定不变的特性,在远程访问、服务器搭建、电商多开、游戏搬砖等场景中显得尤为重要。以下是获取静态IP地址的完整教程,涵盖家庭网络、企业网络和公网静态IP的配置方法: 一、什么是静态IP? 内网IP&…...