3.QT-信号和槽|自定义槽函数|自定义信号}自定义的语法}带参数的信号和槽(C++)

信号和槽

Linux信号 Signal 系统内部的通知机制. 进程间通信的方式.

  1. 信号源:谁发的信号.
  2. 信号的类型:哪种类别的信号
  3. 信号的处理方式:注册信号处理函数,在信号被触发的时候自动调用执行.

Qt中的信号和Linux中的信号,虽然不是一样的概念,但是确实有相似之处

Qt中,谈到信号,也是涉及到三个要素信号源:

  1. 由哪个控件发出的信号
  2. 信号的类型:用户进行不同的操作,就可能触发不同的信号
  • 点击按钮,触发点击信号.
  • 在输入框中移动光标,触发移动光标的信号,勾选一个复选框
  • 选择一个下拉框都会触发出不同的信号
    咱们写的GUI程序,就是要让用户进行操作.就是要和用户进行交互这个过程中就需要关注,用户当前的操作具体是个什么样的操作
  1. 信号的处理方式:槽(slot)=>函数
    Qt中可以使用connect这样的函数,把一个信号和一个槽关联起来后续只要信号触发了,Qt就会自动的执行槽函数

所谓的"槽函数"本质上也是一种"回调函数"(callback)
最早C语言阶段
C 进阶=>指针进阶=>函数指针.

  1. 实现转移表,降低代码的"圈复杂度”.
  2. 实现回调函数效果=〉qsort

后来在C++阶段~

  1. STL中,函数对象/仿函数
  2. lambda 表达式.

后来在Linux中

  1. 信号处理函数
  2. 线程的入口函数.
  3. epoll基于回调的机制

一定是先把信号的处理方式准备好,再触发信号~
Qt中,一定是先关联号信号和槽,然后再触发这个信号.顺序不能颠倒,否则信号就不知道如何处理了(错过了).

信号和槽概述

在Qt中,⽤⼾和控件的每次交互过程称为⼀个事件。⽐如"⽤⼾点击按钮"是⼀个事件,"⽤⼾关闭窗⼝"也是⼀个事件。每个事件都会发出⼀个信号,例如⽤⼾点击按钮会发出"按钮被点击"的信号,⽤⼾关闭窗⼝会发出"窗⼝被关闭"的信号。
Qt中的所有控件都具有接收信号的能⼒,⼀个控件还可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗⼝接收到"按钮被点击"的信号后,会做出"关闭⾃⼰"的响应动作;再⽐如输⼊框⾃⼰接收到"输⼊框被点击"的信号后,会做出"显⽰闪烁的光标,等待⽤⼾输⼊数据"的响应动作。在Qt中,对信号做出的响应动作就称之为槽。
信号和槽是Qt特有的消息传输机制,它能将相互独⽴的控件关联起来。⽐如,"按钮"和"窗⼝"本⾝是两个独⽴的控件,点击"按钮"并不会对"窗⼝"造成任何影响。通过信号和槽机制,可以将"按钮"和"窗⼝"关联起来,实现"点击按钮会使窗⼝关闭"的效果。
![[Pasted image 20250417183130.png]]

信号的本质

信号是由于⽤⼾对窗⼝或控件进⾏了某些操作,导致窗⼝或控件产⽣了某个特定事件,这时Qt对应的窗⼝类会发出某个信号,以此对⽤⼾的操作做出反应。因此,信号的本质就是事件。如:

  • 按钮单击、双击
  • 窗⼝刷新
  • ⿏标移动、⿏标按下、⿏标释放
  • 键盘输⼊
    那么在Qt中信号是通过什么形式呈现给使⽤者的呢?
  • 我们对哪个窗⼝进⾏操作,哪个窗⼝就可以捕捉到这些被触发的事件。
  • 对于使⽤者来说触发了⼀个事件我们就可以得到Qt框架给我们发出的某个特定信号。
  • 信号的呈现形式就是函数,也就是说某个事件产⽣了,Qt框架就会调⽤某个对应的信号函数,通知使⽤者。
    在Qt中信号的发出者是某个实例化的类对象。
槽的本质

槽(Slot)就是对信号响应的函数。槽就是⼀个函数,与⼀般的C++函数是⼀样的,可以定义在类的任何位置(public、protected或private),可以具有任何参数,可以被重载,也可以被直接调⽤(但是不能有默认参数)。槽函数与⼀般的函数不同的是:槽函数可以与⼀个信号关联,当信号被发射时,关联的槽函数被⾃动执⾏。
说明
(1)信号和槽机制底层是通过函数间的相互调⽤实现的。每个信号都可以⽤函数来表⽰,称为信号函数;每个槽也可以⽤函数表⽰,称为槽函数。例如:"按钮被按下"这个信号可以⽤clicked()函数表⽰,"窗⼝关闭"这个槽可以⽤close()函数表⽰,假如使⽤信号和槽机制-实现:"点击按钮会关闭窗⼝"的功能,其实就是clicked()函数调⽤close()函数的效果。
(2)信号函数和槽函数通常位于某个类中,和普通的成员函数相⽐,它们的特别之处在于:

  • 信号函数⽤signals关键字修饰,槽函数⽤public slots、protected slots 或者private slots修 饰。signals和slots是Qt在C++的基础上扩展的关键字,专⻔⽤来指明信号函数和槽函数;
  • 信号函数只需要声明,不需要定义(实现),⽽槽函数需要定义(实现)。
    信号函数的定义是Qt⾃动在编译程序之前⽣成的.编写Qt应⽤程序的程序猿⽆需关注.
    这种⾃动⽣成代码的机制称为元编程(Meta Programming).这种操作在很多场景中都能⻅到.

信号和槽的使⽤

连接信号和槽

在Qt中,QObject类提供了⼀个静态成员函数connect(),该函数专⻔⽤来关联指定的信号函数和槽函数
QObject是Qt内置的⽗类.Qt中提供的很多类都是直接或者间接继承⾃QObject.

connect()函数原型:

connect (const QObject *sender,  const char * signal ,  const QObject * receiver ,  const char * method ,  Qt::ConnectionType type = Qt::AutoConnection )

参数说明:

  • sender:信号的发送者;(哪个控件)
  • signal:发送的信号(信号函数);(信号的类型)
  • receiver:信号的接收者;(控件)
  • method:接收信号的槽函数;(要处理信号的对象提供的成员函数)
  • type:⽤于指定关联⽅式,默认的关联⽅式为Qt::AutoConnection,通常不需要⼿动设定

代码⽰例:在窗⼝中设置⼀个按钮,当点击"按钮"时关闭"窗⼝"。

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button = new QPushButton(this);button->setText("关闭");button->move(200, 200);connect(button, &QPushButton::clicked, this, &Widget::close);
}Widget::~Widget()
{delete ui;
}

所谓的信号也就是Qt中的对象,内部提供的一些成员函数
![[Pasted image 20250417185911.png]]

图标带有锯齿,slot函数,click是一个slot函数,作用就是在调用的时候相当于点击了一下按钮
带有类似wifi的图标,就是信号函数,clicked,才是要触发的点击信号

button, &QPushButton::clicked

connect函数要求,这俩参数是匹配的,button的类型如果是QPushButton*,此时第二个参数的信号必须是QPushButton内置的信号或者父类的信号,不能是其他的类的信号

this, &Widget::close

close是QWidget内置的槽函数,Widget继承自QWidget,也就继承了父亲的槽函数
close槽函数功能已经是内部实现好的,具体作用就是关闭当前的窗口/控件

connect(button, &QPushButton::clicked, this, &Widget::close);

针对button,进行点击操作,Widget就会关闭
![[Pasted image 20250417194027.png]]

具体可以查看Qt文档
![[Pasted image 20250417194426.png]]

connect中的char*参数
但是传入的是&QPushButton::clicked, &Widget::close函数指针
![[Pasted image 20250417201211.png]]

void(*)();
![[Pasted image 20250417201234.png]]

bool(*)();
这两个函数指针的类型也是不同的
![[Pasted image 20250417201402.png]]

这个函数声明,是以前l日版本的Qt的connect函数的声明
以前版本中,传参的写法和现在其实也是有区别的此时,给信号参数传参,要搭配一个SIGNAL宏. 给槽参数传参,搭配一个SLOT宏.
传入的函数指针转成char*

connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::close));

Qt 5开始,对上述写法做出了简化.不再需要写SIGNAL 和SLOT宏了.
给connect提供了重载版本.重载版本中,第二个参数和第四个参数成了泛型参数.允许咱们传入任意类型的函数指针了.
![[Pasted image 20250417201637.png]]

QtPrivate::FunctionPointer<Func1>::ObjectQt封装的类型萃取器
此时connect函数就带有了一定的参数检查功能
如果你传入的第一个参数和第二个参数不匹配,或者第三个参数和第四个参数不匹配.(不匹配,2,4参数的函数指针,不是1,3 参数的成员函数)
此时代码编译出错

自定义槽函数1

widget.cpp

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button = new QPushButton(this);button->setText("按钮");button->move(100, 100);connect(button, &QPushButton::clicked, this, &Widget::handleClicked);
}Widget::~Widget()
{delete ui;
}void Widget::handleClicked()
{//按下按钮,修改窗口标题this->setWindowTitle("按钮已经按下");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handleClicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H

![[Pasted image 20250417202721.png]]

按下按钮
![[Pasted image 20250417202729.png]]

所谓的slot就是一个普通的成员函数
所谓的自定义一个槽函数,操作过程和自定义一个普通的成员函数,没啥区别!在以前版本的Qt中,槽函数必须放到public/private/protected slots:
![[Pasted image 20250417203313.png]]

此处的slots是Qt自己扩展的关键字.(不是C++标准中的语法) Qt里广泛使用了元编程技术. (基于代码,生成代码)
qmake 构建Qt项目的时候,就会调用专门的扫描器,扫描代码中特定的关键字.(slots这种) 基于关键字自动生成一大堆相关的代码,

自定义槽函数2

图形化方式拖入一个PushButton
![[Pasted image 20250417203641.png]]

鼠标右键点击PushButton
![[Pasted image 20250417203929.png]]

点击转到槽
![[Pasted image 20250417203939.png]]

这个窗口列出了QPushButton提供的所有信号,包含了QPushButton父类的信号
双击clicked
![[Pasted image 20250417204153.png]]

直接生成好了一个函数,声明也生成好了
可以直接编写代码

void Widget::on_pushButton_clicked()
{this->setWindowTitle("按钮已经按下");
}

![[Pasted image 20250417204315.png]]

在Qt中,除了通过connect来连接信号槽之外,还可以通过函数名字的方式来自动连接

void Widget::on_pushButton_clicked()

⾃动⽣成槽函数的名称有⼀定的规则。槽函数的命名规则为:on_XXX_SSS,其中:

  1. 以"on"开头,中间使⽤下划线连接起来;
  2. "XXX"表⽰的是对象名(控件的 objectName 属性)。
  3. "SSS"表⽰的是对应的信号。
    如:“on_pushButton_clicked()”,pushButton代表的是对象名,clicked是对应的信号。
    ![[Pasted image 20250417205652.png]]

Qt中调用这个函数的时候,就会触发上述自动连接信号槽的规则!!正是在自动生成的ui_widget.h中调用的~
![[Pasted image 20250417205720.png]]

如果我们通过图形化界面创建控件,还是推荐使用这种快速的方式来连接信号槽
如果我们是通过代码的方式来创建控件,还是得手动connect.(你的代码中没有调用connectSlotsByName)

自定义信号

Qt中也充许自定义信号
自定义槽函数,非常关键.开发中大部分情况都是需要自定义槽函数的槽函数,就是用户触发某个操作之后,要进行的业务逻辑
自定义信号,比较少见.实际开发中很少会需要自定义信号.
信号就对应到用户的某个操作~
在GUI,用户能够进行哪些操作,是可以穷举的~~
Qt内置的信号,基本上已经覆盖到了上述所有可能的用户操作
因此,使用Qt内置的信号,就足以应付大部分的开发场景了,
自定义信号,本身代码比较简单的~
![[Pasted image 20250417211348.png]]

Widget虽然还没有定义任何信号,由于继承自QWidget,和QObject,这俩类里面已经提供了一些信号了,可以直接使用.
所谓的Qt的信号,本质上也就是一个"函数
Qt5以及更高版本中,槽函数和普通的成员函数之间,没啥差别了. 但是,信号,则是一类非常特殊的函数,

  1. 程序员只要写出函数声明,并且告诉Qt,这是一个“信号”即可, 1.
    这个函数的定义,是Qt在编译过程中,自动生成的.(自动生成的过程,程序员无法干预)
    信号在Qt中是特殊的机制.Qt生成的信号函数的实现,要配合Qt框架做很多既定的操作~~
  2. 作为信号函数,这个函数的返回值,必须是void.
    有没有参数都可以.甚至也可以支持重载
    ![[Pasted image 20250417211440.png]]

这个也是Qt自己扩展出来的关键字~~
qmake的时候,调用一些代码的分析/生成工具,
扫描到类中包含signals这个关键字的时候,此时,就会自动的把下面的函数声明认为是信号,并且给这些信号函数自动的生成函数定义
widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
signals:void mySignal();
public slots:void handleMySignal();private:Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this, &Widget::mySignal, this, &Widget::handleMySignal);//发送自定义信号emit mySignal();
}Widget::~Widget()
{delete ui;
}void Widget::handleMySignal()
{this->setWindowTitle("处理自定义信号");
}

如何才能触发出自定义的信号呢?
Qt内置的信号,都不需要咱们手动通过代码来触发
用户在GUI,进行某些操作,就会自动触发对应信号.(发射信号的代码已经内置到Qt框架中了)
自定义的信号需要通过emit,来发射信号

emit mySignal();

![[Pasted image 20250417212346.png]]

在启动的时候直接触发信号
发送信号的操作,可以在任何合适的代码中,不一定非要在构造函数中

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this, &Widget::mySignal, this, &Widget::handleMySignal);}Widget::~Widget()
{delete ui;
}void Widget::handleMySignal()
{this->setWindowTitle("处理自定义信号");
}void Widget::on_pushButton_clicked()
{//发送自定义信号emit mySignal();
}

通过图形化方式创建一个槽函数
![[Pasted image 20250417212730.png]]

点击按钮
![[Pasted image 20250417212736.png]]

点击按钮->
QPushButton::clicked->
Widget::on_pushButton_clicked()->
emit mySignal();->
void Widget::handleMySignal()

其实在Qt5中emit 现在啥都没做
真正的操作都包含在mySignal内部生成的函数定义了
emit mySignal();
即使不写emit,信号也能发出去!!
即使如此,实际开发中,还是建议大家,把emit都加上
加上代码可读性更高,更明显的标识出,这里是发射自定义的信号了.

自定义的基本语法

在Qt中,允许⾃定义信号的发送⽅以及接收⽅,即可以⾃定义信号函数和槽函数。但是对于⾃定义的
信号函数和槽函数有⼀定的书写规范。
1、⾃定义信号函数书写规范

  1. ⾃定义信号函数必须写到"signals"下;
  2. 返回值为void,只需要声明,不需要实现;
  3. 可以有参数,也可以发⽣重载;

2、⾃定义槽函数书写规范

  1. 早期的Qt版本要求槽函数必须写到"public slots"下,但是现在⾼级版本的Qt允许写到类的"public"作⽤域中或者全局下;
  2. 返回值为void,需要声明,也需要实现;
  3. 可以有参数,可以发⽣重载;

3、发送信号
使⽤"emit"关键字发送信号。"emit"是⼀个空的宏。"emit"其实是可选的,没有什么含义,只是为了提醒开发⼈员。

![[Pasted image 20250417213623.png]]

必须先关联再发射
原因是,⾸先关联信号和槽,⼀旦检测到信号发射之后就会⽴⻢执⾏关联的槽函数。反之,若先发射信号,此时还没有关联槽函数,当信号发射之后槽函数不会响应

带参数的信号和槽

Qt的信号和槽也⽀持带有参数,同时也可以⽀持重载.
此处我们要求,信号函数的参数列表要和对应连接的槽函数参数列表⼀致.
此时信号触发,调⽤到槽函数的时候,信号函数中的实参就能够被传递到槽函数的形参当中

signals:void mySignal(const QString& text);public slots:void handleMySignal(const QString& text);

这里的参数必须一致
一致主要是要求类型一致,个数如果不一致也可以,不一致的时候,信号的参数的个数必须比槽的参数的个数更多

void Widget::handleMySignal(const QString& text)
{this->setWindowTitle(text);
}void Widget::on_pushButton_clicked()
{//发送自定义信号emit mySignal("带参数的信号");
}

![[Pasted image 20250417215916.png]]

点击按钮
![[Pasted image 20250417215923.png]]

传参可以起到复用代码的效果
有多个逻辑,逻辑上整体一致,但是涉及到的数据不同,
就可以通过函数-参数来复用代码,并且在不同的场景中传入不同的参数即可~
![[Pasted image 20250417220231.png]]

新建一个PushButton
转到槽,新建一个clicked函数

void Widget::on_pushButton_clicked()
{//发送自定义信号emit mySignal("把标题设置为标题1");
}void Widget::on_pushButton_2_clicked()
{emit mySignal("把标题设置为标题2");
}

![[Pasted image 20250417220435.png]]

![[Pasted image 20250417220440.png]]

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

Qt中很多内置的信号,也是带有参数的.(这些参数不是咱们自己传递的)
clicked信号就带有一个参数~~
![[Pasted image 20250417221013.png]]

这个参数表示当前按钮是否处于“选中”状态这个选中状态对于QPushButton没啥意义,对于QCheckBox复选框,就很有用了,

signals:void mySignal(const QString& text, const QString& text2);public slots:void handleMySignal(const QString& text);
void Widget::on_pushButton_clicked()
{//发送自定义信号emit mySignal("把标题设置为标题1", "");
}void Widget::on_pushButton_2_clicked()
{emit mySignal("把标题设置为标题2", "");
}

信号函数的参数个数,超过了槽函数的参数个数,此时,都是可以正常使用的信号函数的参数个数,少于槽函数的参数个数,此时代码无法编译通过
![[Pasted image 20250417222042.png]]

直观的思考,应该是要求信号的参数个数和槽的参数个数,严格一致
此处为啥允许信号的参数比槽的参数多呢?? 一个槽函数,有可能会绑定多个信号
如果我们严格要求参数个数一致,就意味着信号绑定到槽的要求就变高了,
换而言之,当下这样的规则,就允许信号和槽之间的绑定更灵活了,更多的信号可以绑定到这个槽函数上了,
个数不一致,槽函数就会按照参数顺序,拿到信号的前N个参数
至少需要确保,槽函数的每个参数都是有值的
要求信号给槽的参数,可以有富裕,但是不能少
![[Pasted image 20250417222334.png]]

![[Pasted image 20250417222340.png]]

![[Pasted image 20250417222418.png]]

带有参数的信号,要求信号的参数和槽的参数要一致
类型,个数要满足要求(信号的参数个数要多于槽的参数个数).

widget.h
![[Pasted image 20250417222531.png]]

Qt中如果要让某个类能够使用信号槽(可以在类中定义信号和槽函数)
则必须要在类最开始的地方,写下QOBJECT宏
这个宏能展开成很多额外的代码
![[Pasted image 20250417222727.png]]

如果不加这个宏,这个类编译的时候会报错

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Element UI 中优雅地使用 `this.$loading` 显示和隐藏加载动画

如何在 Element UI 中优雅地使用 this.$loading 显示和隐藏加载动画 在现代 Web 应用开发中&#xff0c;用户体验至关重要。当执行耗时操作&#xff08;如网络请求或数据处理&#xff09;时&#xff0c;显示一个友好的加载动画可以让用户知道系统正在工作&#xff0c;而不是卡…

动态加载内容时selenium如何操作?

当处理动态加载的内容时&#xff0c;Selenium 是一个非常强大的工具&#xff0c;因为它可以模拟真实用户的浏览器行为&#xff0c;等待页面元素加载完成后再进行操作。以下是使用 Selenium 获取动态加载内容的详细步骤和代码示例。 一、安装 Selenium 和 ChromeDriver &#…

力扣第446场周赛

有事没赶上, 赛后模拟了一下, 分享一下我的解题思路和做题感受 1.执行指令后的得分 题目链接如下&#xff1a;力扣 给你两个数组&#xff1a;instructions 和 values&#xff0c;数组的长度均为 n。 你需要根据以下规则模拟一个过程&#xff1a; 从下标 i 0 的第一个指令开…

三维点拟合平面ransac c++

理论 平面的一般定义 在三维空间中&#xff0c;一个平面可以由两个要素唯一确定&#xff1a; 法向量 n(a,b,c)&#xff1a;垂直于平面的方向 平面上一点 平面上任意一点 p(x,y,z) 满足&#xff1a; ( p − p 0 ) ∗ n 0 (p - p0) * n 0 (p−p0)∗n0 即 a ( x − x 0 ) …

基于LSTM-AutoEncoder的心电信号时间序列数据异常检测(PyTorch版)

心电信号&#xff08;ECG&#xff09;的异常检测对心血管疾病早期预警至关重要&#xff0c;但传统方法面临时序依赖建模不足与噪声敏感等问题。本文使用一种基于LSTM-AutoEncoder的深度时序异常检测框架&#xff0c;通过编码器-解码器结构捕捉心电信号的长期时空依赖特征&#…

Docker 部署 PostgreSQL 数据库

Docker 部署 PostgreSQL 数据库 基于 Docker 部署 PostgreSQL 数据库一、拉取 PostgreSQL 镜像二、运行 PostgreSQL 容器三、运行命令参数详解四、查看容器运行状态 基于 Docker 部署 PostgreSQL 数据库 一、拉取 PostgreSQL 镜像 首先&#xff0c;确保你的 Docker 环境已正确…

MySQL性能调优(四):MySQL的执行原理(MYSQL的查询成本)

文章目录 MySQL性能调优数据库设计优化查询优化配置参数调整硬件优化 1.MySQL的执行原理-21.1.MySQL的查询成本1.1.1.什么是成本1.1.2.单表查询的成本1.1.2.1.基于成本的优化步骤实战1. 根据搜索条件&#xff0c;找出所有可能使用的索引2. 计算全表扫描的代价3. 计算使用不同索…

用 Go 优雅地清理 HTML 并抵御 XSS——Bluemonday

1、背景与动机 只要你的服务接收并回显用户生成内容&#xff08;UGC&#xff09;——论坛帖子、评论、富文本邮件正文、Markdown 等——就必须考虑 XSS&#xff08;Cross‑Site Scripting&#xff09;攻击风险。浏览器在解析 HTML 时会执行脚本&#xff1b;如果不做清理&#…

Redis SCAN 命令的详细介绍

Redis SCAN 命令的详细介绍 以下是 Redis SCAN​ 命令的详细介绍&#xff0c;结合其核心特性、使用场景及底层原理进行综合说明&#xff1a; 工作原理图 &#xff1a; ​ 一、核心特性 非阻塞式迭代 通过游标&#xff08;Cursor&#xff09; 分批次遍历键&#xff0c;避免一次…

SpringBoot3集成MyBatis-Plus(解决Boot2升级Boot3)

总结&#xff1a;目前升级仅发现依赖有变更&#xff0c;其他目前未发现&#xff0c;如有发现&#xff0c;后续会继续更新 由于项目架构提升&#xff0c;以前开发的很多公共的组件&#xff0c;以及配置都需要升级&#xff0c;因此记录需要更改的配置&#xff08;记录时间&#…

基于mybatis与PageHelper插件实现条件分页查询(3.19)

实现商品分页例子 需要先引入mybatis与pagehelper插件&#xff0c;在pom.xml里 <!-- Mybatis --> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3&l…

Spring Bean 全方位指南:从作用域、生命周期到自动配置详解

目录 1. Bean 的作用域 1.1 singleton 1.2 prototype 1.3 request 1.4 session 1.5 application 1.5.1 servletContext 和 applicationContext 区别 2. Bean 的生命周期 2.1 详解初始化 2.1.1 Aware 接口回调 2.1.2 执行初始化方法 2.2 代码示例 2.3 源码 [面试题…

C++ (非类型参数)

模板除了定义类型参数之外&#xff0c;也可以在模板内定义非类型参数 非类型参数不是类型&#xff0c;而是值&#xff0c;比如&#xff1a;指针&#xff0c;整数&#xff0c;引用 非类型参数的用法&#xff1a; 1.整数常量&#xff1a;非类型参数最常见的形式是整数常量&…

短视频+直播商城系统源码全解析:音视频流、商品组件逻辑剖析

时下&#xff0c;无论是依托私域流量运营的品牌方&#xff0c;还是追求用户粘性与转化率的内容创作者&#xff0c;搭建一套完整的短视频直播商城系统源码&#xff0c;已成为提升用户体验、增加商业变现能力的关键。本文将围绕三大核心模块——音视频流技术架构、商品组件设计、…

5.QT-常用控件-QWidget|enabled|geometry|window frame(C++)

控件概述 实现图形化界面的程序. Qt中已经给我们提供了很多的“控件" 就需要学习和了解这些控件&#xff0c;学会如何使用这些控件 编程讲究的是“站在巨人的肩膀上”&#xff0c;而不是“从头发明轮子" 一个图形化界面上的内容&#xff0c;不需要咱们全都从零去实…

2025-04-22| Docker: --privileged参数详解

在 Docker 中&#xff0c;--privileged 是一个运行容器时的标志&#xff0c;它赋予容器特权模式&#xff0c;大幅提升容器对宿主机资源的访问权限。以下是 --privileged 的作用和相关细节&#xff1a; 作用 完全访问宿主机的设备&#xff1a; 容器可以访问宿主机的所有设备&am…

高性能服务器配置经验指南1——刚配置好服务器应该做哪些事

文章目录 安装ubuntu安装必要软件设置用户远程连接安全问题ClamAV安装教程步骤 1&#xff1a;更新系统软件源步骤 2&#xff1a;升级系统&#xff08;可选但推荐&#xff09;步骤 3&#xff1a;安装 ClamAV步骤 4&#xff1a;更新病毒库步骤 5&#xff1a;验证安装ClamAV 常用命…

直流绝缘监测解决方案:保障工业与新能源系统的安全运行

一、引言 随着工业自动化和新能源技术的快速发展&#xff0c;直流供电系统在光伏发电、储能电站、电动汽车充电桩等领域的应用日益广泛。然而&#xff0c;直流系统的正负极不接地&#xff08;IT系统&#xff09;特性&#xff0c;使得绝缘故障可能导致漏电、短路甚至设备损毁等…

VSCode 用于JAVA开发的环境配置,JDK为1.8版本时的配置

插件安装 JAVA开发在VSCode中&#xff0c;需要安装JAVA的必要开发。当前安装只需要安装 “Language Support for Java(TM) by Red Hat”插件即可 安装此插件后&#xff0c;会自动安装包含如下插件&#xff0c;不再需要单独安装 Project Manager for Java Test Runner for J…

C++入门语法

C入门 首先第一点&#xff0c;C中可以混用C语言中的语法。但是C语言是不兼容C的。C主要是为了改进C语言而创建的一门语言&#xff0c;就是有人用C语言用不爽了&#xff0c;改出来个C。 命名空间 c语言中会有如下这样的问题&#xff1a; 那么C为了解决这个问题就整出了一个命名…