当前位置: 首页 > news >正文

关于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信号、槽、槽函数的讲解

也是好久没有发帖子了&#xff0c;最近博主主要还是在边学QT边完成任务&#xff0c;所以进度很慢&#xff0c;但确实在这几天对于QT自身槽和信号这类特殊的机制有了一定简单的理解&#xff0c;所以还是想记录下来&#xff0c;如果有初学者看到帖子对他有一定的帮助&#xff0c;…...

算法训练营第三十天 | 动态规划 (三)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、01背包问题理论基础&#xff08;一&#xff09;动态规划五部曲确定dp数组以及下标的含义确定递推公式初始化dp数组确定遍历顺序 二、01背包问题理论基础&#…...

Vue开发网站会有“#”原因是前端路由使用了 Hash 模式

前言 网站链接中出现 #&#xff08;井号&#xff09;是因为你的前端路由使用了 Hash 模式&#xff08;hash mode&#xff09;&#xff0c;这是一种前端框架&#xff08;如 Vue.js、React 等&#xff09;中常用的路由策略。 为什么有 # 比如 https://www.zimeinew.com/#/order…...

SpringBootTest报错

Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or … 解决方案&#xff1a;在SpringTest注解中添加属性&#xff08;classes &#xff09;填写启动类 如我的启动类是MainApplication.class javax.websocket.server.ServerContainer no…...

【质量管理】现代TRIZ(萃智)理论概述

一、什么是TRIZ理论 TRIZ理论,即发明问题解决理论(Teoriya Resheniya Izobreatatelskikh Zadatch),是由前苏联发明家根里奇阿奇舒勒(Genrich S. Altshuller)于1946年创立的。它是一门基于知识的、面向人的发明问题解决系统化方法学。TRIZ理论通过研究大量的专利,总结出技…...

前端面经-JS篇(四)--回调地狱、promise异步编程、Proxy 与 Reflect 、模块化

一、回调地狱 回调地狱&#xff08;Callback Hell&#xff09;&#xff0c;也称为回调地狱&#xff0c;是指在 JavaScript 中处理多个嵌套的异步回调函数时&#xff0c;代码结构变得非常难以阅读和维护的现象。 为什么会出现回调地狱&#xff1f; 回调地狱通常出现在需要执行…...

【oql】spark thriftserver内存溢出,使用oql查询导致oom的sql

eclipse memory analyzer (mat)软件内的OQL实现查询内促信息。 帮助信息&#xff1a;软件Help/Help Contents/Querying Heap Objects (OQL) 就是查询SparkExecuteStatementOperation 的statement 字段。 select objects s.statement from org.apache.spark.sql.hive.thriftser…...

算法设计与分析(基础)

问题列表 一、 算法的定义与特征&#xff0c;算法设计的基本步骤二、 算法分析的目的是什么&#xff1f;如何评价算法&#xff0c;如何度量算法的复杂性&#xff1f;三、 递归算法、分治法、贪婪法、动态规划法、回溯法的基本思想方法。四、 同一个问题&#xff0c;如TSP&#…...

爬虫学习——使用HTTP服务代理、redis使用、通过Scrapy实现分布式爬取

一、使用HTTP服务代理 由于网络环境、网站对用户的访问速度的限制等原因&#xff0c;使得爬取过程会出现IP被封禁&#xff0c;故使用代理可提高爬取速度。在Scrapy中提供了一个HttpProxyMiddleware专门用于进行爬虫代理设置。在使用该代理进行爬取操作时&#xff0c;需要先在ba…...

机器学习中的特征存储是什么?我需要一个吗?

本质上,特征存储是一个专用存储库,用于系统地存储和排列特征,主要用于数据科学家训练模型,并帮助已训练模型的应用程序进行预测。它是一个关键的聚合点,人们可以在此构建或修改从各种数据源提取的特征集合。此外,它还支持从这些特征组中创建和增强新的数据集,以满足处于…...

【C语言】C语言中的联合体与枚举类型

前言 在C语言中&#xff0c;联合体&#xff08;union&#xff09;和枚举&#xff08;enum&#xff09;是两种非常实用但又常被忽视的自定义数据类型。它们在内存管理、代码可读性以及程序设计的灵活性方面都有着独特的优势。今天&#xff0c;我们就来深入探讨一下联合体和枚举…...

Golang编程拒绝类型不安全

button-chen/containertypesafe-go: 使用泛型包装标准库的容器 list、ring、heap、sync.Pool 和 sync.Map&#xff0c;实现类型安全 简介 在 Go 中&#xff0c;标准库提供了多种容器类型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;这些容器默认…...

炼锌废渣提取钴工艺流程

炼锌废渣中提取钴的工艺流程通常结合湿法冶金技术&#xff0c;针对废渣中钴与锌、铁、铜等金属的复杂共生特性&#xff0c;通过预处理、浸出、除杂、钴富集及提纯等步骤实现钴的高效回收。以下是典型工艺流程的详细说明&#xff1a; 一、预处理 炼锌废渣&#xff08;如锌浸出…...

Restful接口学习

一、为什么RESTful接口是数据开发的核心枢纽&#xff1f; 在数据驱动的时代&#xff0c;RESTful接口如同数据高速公路上的收费站&#xff0c;承担着数据交换的核心职责。数据工程师每天需要面对&#xff1a; 异构系统间的数据交互&#xff08;Hadoop集群 ↔ 业务系统&#xf…...

仿真每日一练 | ABAQUS应力松弛

应力松弛是弹性材料在应力作用下产生微塑性变形&#xff0c;并且逐渐积累&#xff0c;在保持应变或者位移不变的前提下&#xff0c;表现为应力逐渐下降的现象。今天介绍一个ABAQUS中应力松弛的相关案例&#xff0c;模型如下所示&#xff1a; 图1 模型认识 回顾一下ABAQUS的有限…...

智能电网第4期 | 电力设备全连接组网方案:从有线到无线无缝融合

随着新型电力系统建设的加速推进&#xff0c;电力设备通信网络正面临前所未有的挑战与机遇。在变电站自动化、输电线路监测、配电房智能化等场景中&#xff0c;传统通信方案已难以满足日益增长的连接需求&#xff1a; 环境复杂性&#xff1a;变电站强电磁干扰环境下需保障微秒级…...

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)

安全便捷无依赖&#xff0c;不学就会无感觉。 笔记模板由python脚本于2025-04-24 20:00:05创建&#xff0c;本篇笔记适合正在研究字符串编码制式的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述。 P…...

机器学习--线性回归模型

阅读本文之前&#xff0c;可以读一读下面这篇文章&#xff1a;终于有人把线性回归讲明白了 0、引言 线性回归作为统计学与机器学习的入门算法&#xff0c;以其简洁优雅的数学表达和直观的可解释性&#xff0c;在数据分析领域占据重要地位。这个诞生于19世纪的经典算法&#xf…...

HTML应用指南:利用GET请求获取微博签到位置信息

在当今数字化时代&#xff0c;社交媒体平台已成为人们日常生活中不可或缺的一部分。作为中国最受欢迎的社交平台之一&#xff0c;微博不仅为用户提供了一个分享信息、表达观点的空间&#xff0c;还通过其丰富的功能如签到服务&#xff0c;让用户能够记录自己生活中的点点滴滴。…...

如何检测Python项目哪些依赖库没有使用

要检测Python项目中哪些依赖库未被使用&#xff0c;可以采用以下方法&#xff1a; 1. 使用静态分析工具 vulture&#xff1a;静态分析工具&#xff0c;检测未使用的代码和导入 pip install vulture vulture your_project/pyflakes&#xff1a;检查未使用的导入语句 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

随着人工智能的快速发展&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09;技术日益受到关注。向量数据库作为 RAG 系统的核心基础设施&#xff0c;堪称 RAG 的“记忆中枢”&#xff0c;其性能直接关系到大模型生成内容的精准度与…...

WHAT - 区分 Git PR 和 MR

文章目录 PR&#xff08;Pull Request&#xff09;MR&#xff08;Merge Request&#xff09;相同点总结 git pr 和 git mr 本质上都是「合并请求」的意思&#xff0c;但它们对应的是不同的平台术语。 PR&#xff08;Pull Request&#xff09; 平台&#xff1a;GitHub、Bitbuc…...

Axure复选框组件的深度定制:实现自定义大小、颜色与全选功能

在产品设计中&#xff0c;复选框作为用户与界面交互的重要元素&#xff0c;其灵活性直接影响到用户体验。本文将介绍如何利用Axure RP工具&#xff0c;通过高级技巧实现复选框组件的自定义大小、颜色调整&#xff0c;以及全选功能的集成&#xff0c;为产品原型设计增添更多可能…...

Datawhale AI春训营——用AI帮助老人点餐

详细内容见官网链接&#xff1a;用AI帮助老人点餐-活动详情 | Datawhale...

两段文本比对,高亮出差异部分

用法一:computed <div class"card" v-if"showFlag"><div class"info">*红色背景为已删除内容&#xff0c;绿色背景为新增内容</div><el-form-item label"与上季度比对&#xff1a;"><div class"comp…...

uniapp 仿小红书轮播图效果

通过对小红书的轮播图分析&#xff0c;可得出以下总结&#xff1a; 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下&#xff1a; <template><view> <!--轮播--><s…...

审计效率升级!快速匹配Excel报表项目对应的Word附注序号

财务审计报告一般包括&#xff1a;封面、报告正文、财务报表&#xff08;Excel工作簿&#xff09;以及对应的财务报表附注&#xff08;Word文档&#xff09;、事务所营业执照以及注册会计师证件。 在审计报告出具阶段&#xff0c;为各报表项目填充对应的Word附注序号&#xff…...

Python 中 `r` 前缀:字符串处理的“防转义利器”

# Python 中 r 前缀&#xff1a;字符串处理的“防转义利器” 在 Python 编程过程中&#xff0c;处理字符串时经常会遇到反斜杠 \ 带来的转义问题&#xff0c;而 r 前缀的出现有效解决了这一困扰。它不仅能处理反斜杠的转义&#xff0c;还在多种场景下发挥着重要作用。接下来&a…...

1️⃣6️⃣three.js_光源

16、光源 3D虚拟工厂在线体验 在 Three.js 中&#xff0c;环境光&#xff08;AmbientLight&#xff09;、点光源&#xff08;PointLight&#xff09;、平行光&#xff08;DirectionalLight&#xff09;、 聚光灯&#xff08;SpotLight&#xff09;、半球光&#xff08;Hemisph…...

AD16如何执行DRC检测

AD16如何执行DRC检测 DRC检测主要用来查看走线是否出现通断&#xff0c;以及是否出现短路。 1)、点击“Tools”---“Design Rule Check…” 2)、全部勾选 3)、勾选“Electrical”中的“Batch”选项&#xff0c;参与DRC检测 4)、勾选“Routing”中的“Batch”选项&#xff0c;…...

PostgreSQL性能优化实用技巧‌

PostgreSQL的性能优化需从‌索引设计、查询调优、参数配置、硬件资源‌等多维度入手。以下为实战中验证有效的优化策略&#xff0c;适用于高并发、大数据量等场 一、索引优化&#xff1a;精准加速查询‌ ‌1.选择正确的索引类型‌ ‌BRIN索引‌&#xff1a;对按时间或数值顺…...

Vue3 ref与props

ref 属性 与 props 一、核心概念对比 特性ref (标签属性)props作用对象DOM 元素/组件实例组件间数据传递数据流向父组件访问子组件/DOM父组件 → 子组件响应性直接操作对象单向数据流&#xff08;只读&#xff09;使用场景获取 DOM/调用子组件方法组件参数传递Vue3 变化不再自…...

SpringBoot | 构建客户树及其关联关系的设计思路和实践Demo

关注&#xff1a;CodingTechWork 引言 在企业级应用中&#xff0c;客户关系管理&#xff08;CRM&#xff09;是核心功能之一。客户树是一种用于表示客户之间层级关系的结构&#xff0c;例如企业客户与子公司、经销商与下级经销商等。本文将详细介绍如何设计客户树及其关联关系…...

SpringCloud——负载均衡

一.负载均衡 1.问题提出 上一篇文章写了服务注册和服务发现的相关内容。这里再提出一个新问题&#xff0c;如果我给一个服务开了多个端口&#xff0c;这几个端口都可以访问服务。 例如&#xff0c;在上一篇文章的基础上&#xff0c;我又新开了9091和9092端口&#xff0c;现在…...

Springboot3+ JDK21 升级踩坑指南

目录 GetMapping和 RequestBody 一起使用时&#xff0c;会把请求方式由GET变为POST 变更默认的httpClient feign 超时配置失效 GetMapping和 RequestBody 一起使用时&#xff0c;会把请求方式由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&#xff0c;以及开放好kafka端口9092&#xff08;如果有修改 过端口的开放对应端口就好&#xff09; …...

第十节:性能优化高频题-虚拟DOM与Diff算法优化

优化策略&#xff1a;同层比较、静态节点标记、最长递增子序列算法 Key的作用&#xff1a;精确识别节点身份 虚拟DOM与Diff算法深度优化策略解析 一、核心优化策略 同层比较机制 Diff算法仅对比同一层级的虚拟节点&#xff0c;避免跨层级遍历带来的性能损耗。 • 实现原理&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 # 因为默认是集群内访问的&#xff0c;需要追加 NodePort访问类型 vim recommended.yaml …...

软考:数值转换知识点详解

文章目录 1. 进制转换1.1 二进制&#xff08;Binary&#xff09;、八进制&#xff08;Octal&#xff09;、十进制&#xff08;Decimal&#xff09;、十六进制&#xff08;Hexadecimal&#xff09;之间的转换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数据恢复环境&#xff1a; QNAP TS-532X NAS设备中有两块1T的SSD固态硬盘和3块5T的机械硬盘。三块机械硬盘组建了一组RAID5阵列&#xff0c;两块固态硬盘组建RAID1阵列。划分了一个存储池&#xff0c;并通过精简LVM划分了7个lv。 NAS故障&#xff1a; 硬盘故障导致无法正常…...

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 中用于线程同步的两个核心类&#xff1a;QMutex 和 QMutexLocker。 &#x1f9f1; 一、什么是 QMutex&#xff1f; QMutex 是 Qt 中的互斥锁&#xff08;mutex&#xff09;类&#xff0c;用于防止多个…...

如何获取静态IP地址?完整教程

静态IP地址&#xff0c;因其固定不变的特性&#xff0c;在远程访问、服务器搭建、电商多开、游戏搬砖等场景中显得尤为重要。以下是获取静态IP地址的完整教程&#xff0c;涵盖家庭网络、企业网络和公网静态IP的配置方法&#xff1a; 一、什么是静态IP&#xff1f; 内网IP&…...