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

qt-C++笔记之信号与槽

qt-C++笔记之信号与槽

code review!

本文抄自公众号:嵌入式小生

文章目录

  • qt-C++笔记之信号与槽
    • 一.信号
      • 2.1.信号的发出
      • 2.2.信号的处理
    • 二.槽函数
      • 2.1.带有默认参数的信号和槽函数
      • 2.2.使用QObject::connect()将信号连接到槽函数的三种方法
        • 2.2.1.第一种方法:使用函数指针
        • 2.2.2.第二种方法:连接到C++11的lambda
        • 2.2.3.第三种方法:使用QObject::connect()以及信号和槽声明宏。
      • 2.3.信号和槽函数的一些高级用法
      • 2.4.使用disconnect断开信号/槽连接
    • 三.使用Qt与第三方信号和槽函数
    • 四.SIGNAL()和SLOT()是Qt定义的两个宏
    • 五.Qt中QEvent和信号槽的区别——未完,没搞明白,搞明白就补充
    • 六.阿西拜编程——信号与槽部分PPT
    • 七.通过函数名称将信号与槽关联
    • 八.ChatGpt——信号与槽
      • 8.1.一些常见的信号与槽的用法
      • 8.2.this指针
      • 8.3.使用特定的函数命名约定可以自动将信号与槽关联
      • 8.4.一个例程

在这里插入图片描述

一.信号

2.1.信号的发出

由于某种条件到达可能引起了对象改变,其内部状态将发生改变,这时候对象就会发出信号。信号是公共访问函数,可以从任何地方发出,但是建议:【只从定义该信号的类及其子类发出信号】。

在Qt框架下,信号发出分为两种:

1、【每个类预定义的信号】:这些信号何时发出可以通过查看官方文档获知。

2、【自定义的信号】:这些信号的发出由开发人员自行定义。

2.2.信号的处理

当一个信号发出时,连接到它的槽函数通常会立即执行,就像一个普通函数调用一样。在这种情况下,信号和槽函数机制是完全独立于GUI事件循环的,也并不会干扰GUI的事件循环。emit语句之后的代码将在所有槽函数都返回之后才执行。如果使用排队连接(queued connections),情况略有不同,在这种情况下,emit关键字后面的代码将立即继续,槽函数将在后续执行。

如果几个槽函数连接到同一个信号上,当信号发出时,这些槽函数将按照它们连接时的顺序依次执行【这一点很重要】。

信号是由moc工具自动生成,不能在.cpp文件中实现,所以信号永远不能有返回类型(必须使用void关键字定义信号)。

关于信号和槽参数的注意事项:经验表明,如果信号和槽函数不使用特殊类型,那么代码具有极强的可重用性。

下表是使用connect()创建信号和槽函数连接时,可以指定5种不同的连接类型:

序号类型含义
1Qt::AutoConnection如果接收者生活在发出信号的线程中,Qt::DirectConnection被使用。否则,使用Qt::QueuedConnection。连接类型是在信号发出时确定。【这是Qt创建信号和槽函数时的默认连接方式】
2Qt::DirectConnection当信号发出时,槽函数立即被调用。槽函数在发送信号的线程中执行。
3Qt::QueuedConnection当控制返回到接收方线程的事件循环时,将调用槽函数。槽函数在接收方的线程中执行。
4Qt::BlockingQueuedConnection与Qt::QueuedConnection相同,只是在槽函数返回之前线程会阻塞。如果接收方存在于发送信号的线程中,则不能使用此连接,否则应用程序将会死锁。
5Qt::UniqueConnection这是一个标志,可以使用按位OR与上述的连接类型进行组合。当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将失败(例如,如果相同的信号已经连接到同一对对象的相同槽位)。注:这个标志在Qt 4.6中引入。

二.槽函数

当一个连接到槽函数的信号被发射时,槽函数将被调用。槽函数是普通的C++函数,在实际开发中也可以正常调用;它们唯一的特点是:【信号可以与它们相连接】。

由于槽是普通的成员函数,所以它们在直接调用时遵循普通的C++规则。但是,作为槽函数时,任何组件都可以通过信号连接从而调用它们。

还可以将槽函数定义为虚拟的,这在开发中非常有用。

与回调机制相比,信号和槽函数机制的速度稍微慢一些,这一点对于实际应用程序来说,这种差别并不显著。一般来说,发送一个连接到某些槽函数的信号,比直接调用非虚函数要慢大约10倍。这是定位连接对象、安全地遍历所有连接(即检查后续接收方在发射过程中没有被销毁)以及以函数调用增加的开销。虽然10个非虚函数调用听起来很多,但是它比new操作或delete操作的开销要小得多。一旦在后台执行一个需要new或delete的字符串、向量或列表操作,信号和槽函数的开销只占整个函数调用开销的很小一部分。在槽函数中执行系统调用时也是如此(或间接调用超过十个函数)。因此信号和槽函数机制的简单性和灵活性是值得的,这些开销在实际应用场景下甚至不会注意到。

注意,当与基于Qt的应用程序一起编译时,定义为信号或槽的变量的第三方库可能会导致编译器出现警告和错误。要解决这个问题,使用#undef来定义出错的预处理器符号即可。

2.1.带有默认参数的信号和槽函数

信号和槽可以包含参数,参数可以有默认值。例如:QObject::destroyed():

void destroyed(QObject* = nullptr);

当QObject被删除时,它会发出这个QObject::destroyed()信号。无论我们在哪里有一个悬空引用指向已删除的QObject,都希望捕捉到这个信号,这样就可以清除它。合适的槽参数可以是:

void objectDestroyed(QObject* obj = nullptr);

2.2.使用QObject::connect()将信号连接到槽函数的三种方法

2.2.1.第一种方法:使用函数指针
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);

将QObject::connect()与函数指针一起使用有几个优点。它允许编译器检查信号的参数是否与槽的参数兼容。当然,编译器还可以隐式地转换参数。

2.2.2.第二种方法:连接到C++11的lambda
connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });

在这种情况下,我们在connect()调用中提供这个上下文。上下文对象提供关于应该在哪个线程中执行接收器的信息。
当发送方或上下文被销毁时,lambda将断开连接。注意:当信号发出时,函数内部使用的所有对象依然是激活的。

2.2.3.第三种方法:使用QObject::connect()以及信号和槽声明宏。

在SIGNAL()和SLOT()宏中包含参数(如果参数有默认值)的规则是:传递给SIGNAL()宏的参数不能少于传递给SLOT()宏的参数。

例如以下代码都是合法的:

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));

但是这种是非法的:

connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));

因为槽函数期望的是一个信号不会发送的QObject。此连接将报告运行时错误。

注意,使用这种方法时,在使用QObject::connect()关联信号和槽函数时,编译器不会自动检查信号和槽函数的参数之间是否匹配。

综上:使用第一种方法 创建信号和槽 在开发中较为常用,也较为合适。

2.3.信号和槽函数的一些高级用法

当需要获取信号发送方的信息时,使用Qt提供QObject::sender()函数,该函数返回一个指向发送信号对象的指针。

Lambda表达式是传递自定义参数到槽的一种方便方式:

connect(action, &QAction::triggered, engine,[=]() { engine->processAction(action->text()); });

2.4.使用disconnect断开信号/槽连接

disconnect()用于断开对象发送器中的信号与对象接收器中的方法的连接。如果连接成功断开,则返回true;否则返回false。

当对信号/槽关联的两方中的任何一个对象进行销毁时,信号/槽连接将被移除。

disconnect()有三种使用方法,如下示例所示:

1、断开所有与对象相连的信号/槽:

disconnect(myObject, nullptr, nullptr, nullptr);

相当于非静态重载函数:

myObject->disconnect();

2、断开所有与特定信号相连的对象:

disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr);

相当于非静态重载函数:

myObject->disconnect(SIGNAL(mySignal()));

3、断开特定接收对象的连接:

disconnect(myObject, nullptr, myReceiver, nullptr);

相当于非静态重载函数:

myObject->disconnect(myReceiver);

nullptr可以用作通配符,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何槽”。

如下格式的使用示例:

disconnect(发送对象,信号,接收对象,方法)

发送对象不会是nullptr。

如果信号为nullptr,将断开接收对象和槽函数与所有信号的连接。否则只断开指定的信号。

如果接收对象是nullptr,它断开所有关联该信号的连接。否则,只断开与接收对象的槽函数连接。

如果方法是nullptr,它会断开任何连接到接收对象的连接。如果不是,只有命名为方法的槽函数连接将被断开。如果没有接收对象,方法必须为nullptr。即:

disconnect(发送对象,信号,nullptrnullptr

三.使用Qt与第三方信号和槽函数

当第三方库中也有信号/槽函数机制时,这时候又需要使用Qt的信号和槽函数机制。对于这种开发场景,Qt可以在同一个项目中使用这两种机制。需将下面一行添加到qmake项目(.pro)工程配置文件中:

CONFIG += no_keywords
该配置将告诉Qt不要定义moc关键字信号、槽函数和emit,因为这些名称将被第三方库使用(例如Boost)。如果要在使用no_keywords标志下继续使用Qt信号和槽机制,需将源文件中所有的Qt moc关键字替换为对应的Qt宏:Q_SIGNALS(或Q_SIGNAL)、Q_SLOT(或Q_SLOT)和Q_EMIT。

四.SIGNAL()和SLOT()是Qt定义的两个宏

SIGNAL()和SLOT()是Qt定义的两个宏,它们返回其参数的C语言风格的字符串(const char*)。因此,下面关联信号和槽的两个语句是等同的:

connect(button,SIGNAL(clicke()),this,SLOT(showArea()));
connect(button,"clicked()",this,"showArea()");

五.Qt中QEvent和信号槽的区别——未完,没搞明白,搞明白就补充

六.阿西拜编程——信号与槽部分PPT

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

七.通过函数名称将信号与槽关联

在Qt Designer中提供了一个快速关联信号和槽函数的方式:使用『转到槽…』对话框创建选定控件之间的信号和槽函数关联。
在这里插入图片描述

在这里插入图片描述

从上图可知,首先QObject和QWidget下的信号是公共的,QAbstractButton是按钮类独有的,Qt使用该类抽象出了按钮的一些公共操作,并已定义好具体的信号。当选中具体信号后,点击“确定”按钮,QtCreator会自动生成一个槽函数,例如,如果选择了clicked()这个信号,则会在代码中生成如下代码,在头文件生成代码如下:
在这里插入图片描述

本质上,QtCreator生成代码的成员函数的命名是能够被QMetaObject的自动连接工具识别的,在构建过程中,在uic生成的用于描述界面的C++文件中,会出现以下代码:
在这里插入图片描述

因此,通过connectSlotByName()就将名称和槽函数进行了关联,该函数会递归搜索给定对象的所有子对象,并将它们的匹配信号连接到遵循特定格式命名的槽函数,格式如下:

void on_<object name>_<signal name>(<signal parameters>)
  • :对象名称。
  • :信号名称。
  • :传入的参数。

在实际使用过程中,只需要声明和实现一个槽函数,其名称遵循标准约定,就可以将一个控件对象的信号和具体槽函数关联,当然这个过程由QtCreator自动完成。

Qt提供的信号和槽函数的自动连接机制,为开发小部件提供了标准命名约定和显式接口。通过提供实现给定界面的源代码,在设计用户界面时无需再编写代码就可以检查设计是否真正有效了。

总结

基于QtCreator,提供的信号和槽函数的自动连接机制在实际开发中,经常会被使用到,特别是在需要快速验证功能和需求的时候,这种方式比使用connect()关联信号和槽函数的开发效率要快很多。但是,如果界面中同类型控件较多的情况下,就需要注释清楚,不然不好区分具体控件下的功能。

在实际项目开发中,对于自定义的信号,习惯使用connect()进行槽函数的关联。对于具体界面中控件,如果是Qt提供的标准控件,则可以使用信号和槽函数的自动连接机制,以加快开发效率。

八.ChatGpt——信号与槽

8.1.一些常见的信号与槽的用法

Qt是一个强大的C++框架,它提供了多种形式的信号与槽机制,用于在应用程序中管理事件和数据流。以下是一些常见的信号与槽的用法:

  1. 基本信号与槽连接:

    QObject::connect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()));
    
  2. 信号与槽连接,传递参数:

    QObject::connect(sender, SIGNAL(mySignal(int, QString)), receiver, SLOT(mySlot(int, QString)));
    
  3. 使用Lambda表达式连接信号与槽:

    QObject::connect(sender, &Sender::mySignal, receiver, [=](int value) {// 处理信号
    });
    
  4. 断开信号与槽连接:

    QObject::disconnect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()));
    
  5. 使用Qt5新的连接语法:

    QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot);
    
  6. 使用Qt的QueuedConnection连接信号与槽,实现跨线程通信:

    QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::QueuedConnection);
    
  7. 自定义信号:

    class MyObject : public QObject {Q_OBJECTpublic:void myFunction() {// 发射自定义信号emit mySignal();}signals:void mySignal();
    };
    
  8. 重载信号:

    class MyObject : public QObject {Q_OBJECTpublic slots:void mySlot(int value) {// 处理整数参数}signals:void mySignal(int value);
    };
    
  9. 信号连接到多个槽函数:

    QObject::connect(sender, SIGNAL(mySignal()), receiver1, SLOT(mySlot1()));
    QObject::connect(sender, SIGNAL(mySignal()), receiver2, SLOT(mySlot2()));
    
  10. 连接同一信号的多个槽函数,指定连接类型:

    QObject::connect(sender, SIGNAL(mySignal()), receiver1, SLOT(mySlot1()), Qt::DirectConnection);
    QObject::connect(sender, SIGNAL(mySignal()), receiver2, SLOT(mySlot2()), Qt::QueuedConnection);
    

这些是Qt中信号与槽的常见用法示例,Qt的信号与槽机制非常灵活,可以适应多种不同的场景和需求。

8.2.this指针

在Qt中,通常可以使用this指针将当前对象(QObject的派生类)连接到信号和槽。以下是一些使用this指针的示例:

  1. 使用this指针将当前对象连接到信号和槽:
QObject::connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));

这将连接当前对象的mySignal信号到当前对象的mySlot槽函数。

  1. 使用Lambda表达式连接信号和槽,其中this指针也可以使用:
QObject::connect(this, &MyClass::mySignal, this, [this]() {// 使用this指针处理信号
});
  1. 自定义信号和槽函数,并在类的方法内连接:
class MyClass : public QObject {Q_OBJECTpublic slots:void mySlot() {// 处理槽函数的逻辑}public:void connectSignalsAndSlots() {QObject::connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));}signals:void mySignal();
};

上述示例中,connectSignalsAndSlots方法连接了当前对象的mySignal信号到当前对象的mySlot槽函数。

使用this指针连接信号与槽是非常常见的,特别是在一个类内部的方法中连接信号与槽,以确保连接正确的对象。但请注意,当断开信号与槽连接时,也需要使用相同的this指针。

8.3.使用特定的函数命名约定可以自动将信号与槽关联

在Qt C++中,使用特定的函数命名约定可以自动将信号与槽关联。这一约定通常用于与Qt Designer或Qt Creator的UI设计器一起工作,以便在UI元素发出信号时,自动生成槽函数。以下是关于这一方式的详细解释:

  1. 函数命名约定
    通常,函数命名约定的格式是:void on_<object name>_<signal name>(<signal parameters>);。这个函数名称中包括了以下部分:

    • on_:前缀,表示这是一个槽函数。
    • <object name>:发送信号的对象的名称,通常是Qt Designer或Qt Creator中为UI元素分配的名称。
    • <signal name>:信号的名称,表示与UI元素关联的信号。
    • <signal parameters>:信号的参数列表,如果信号带有参数的话。
  2. 自动生成槽函数
    当你使用Qt Designer或Qt Creator的UI设计器来创建UI界面时,你可以在设计器中选择一个UI元素(例如按钮、复选框等),然后在属性编辑器中为该元素分配名称并选择要关联的信号。UI设计器会自动创建与该信号关联的槽函数,并使用上述命名约定来命名该函数。

  3. 示例
    假设你在UI设计器中有一个名为pushButton的按钮,并希望在点击按钮时触发一个槽函数。你可以将按钮的clicked信号与槽函数关联,然后Qt会自动为你生成槽函数。槽函数的命名约定如下:

    void on_pushButton_clicked();
    

    当按钮被点击时,这个槽函数会自动被调用。

这种函数命名约定使信号与槽的关联变得更加简单,尤其对于与UI元素的交互非常有用。这样的自动生成槽函数提高了代码的可读性和维护性,因为开发人员可以轻松识别哪些槽函数与UI元素关联。

需要注意的是,这种方式在Qt的UI设计器工具中特别有用,但如果你需要手动创建信号与槽的关联或需要更多的灵活性,还是可以使用QObject::connect来手动连接信号与槽。

8.4.一个例程

以下是一个使用this指针形式的完整Qt C++示例,演示如何创建一个简单的Qt应用程序并实现信号与槽的不同形式。这个示例包括使用this指针连接信号与槽的不同情况:

#include <QCoreApplication>
#include <QObject>
#include <QDebug>class MyObject : public QObject {Q_OBJECTpublic slots:void slot1() {qDebug() << "Slot 1 called";}void slot2(int value) {qDebug() << "Slot 2 called with value: " << value;}signals:void signal1();
};int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);MyObject obj;// 连接信号与槽,使用this指针QObject::connect(&obj, SIGNAL(signal1()), &obj, SLOT(slot1()));QObject::connect(&obj, SIGNAL(signal1()), &obj, SLOT(slot2(int)));// 发射信号emit obj.signal1();return app.exec();
}#include "main.moc" // 自动生成的moc文件

在这个示例中,我们创建了一个名为MyObject的自定义QObject派生类,该类包括两个槽函数:slot1slot2,以及一个信号函数signal1。在main函数中,我们创建了一个MyObject对象,并使用this指针将其信号和槽连接在一起。

  • 使用QObject::connect函数,我们将signal1信号连接到slot1slot2槽函数,以便在发射信号时调用这些槽函数。
  • 通过emit关键字,我们触发了signal1信号的发射。

当运行这个应用程序时,它将输出:

Slot 1 called
Slot 2 called with value: 0

这个示例展示了如何使用this指针在同一对象内部连接信号与槽,以及如何传递参数给槽函数。这是Qt中信号与槽机制的一个基本用法。

相关文章:

qt-C++笔记之信号与槽

qt-C笔记之信号与槽 code review! 本文抄自公众号&#xff1a;嵌入式小生 文章目录 qt-C笔记之信号与槽一.信号2.1.信号的发出2.2.信号的处理 二.槽函数2.1.带有默认参数的信号和槽函数2.2.使用QObject::connect()将信号连接到槽函数的三种方法2.2.1.第一种方法&#xff1a;使…...

linux安装visual studio code

下载 https://code.visualstudio.com/ 下载.deb文件 安装 假如文件被下载到了 /opt目录下 进入Opt目录&#xff0c;右键从当前目录打开终端。 输入下面的安装命令。 sudo apt-get install ./code_1.83.1-1696982868_amd64.deb 安装成功。 配置 打开 visual studio cod…...

VM虚拟机创建centos7 64位系统提示此主机不支持64位客户机操作系统,此系统无法运行

VM虚拟机创建centos7 64位系统提示此主机不支持64位客户机操作系统,此系统无法运行 背景解决方案 背景 本身系统是window10 64位专业版系统&#xff0c;理论上不应该不支持64位的。 解决方案 最近安装docker开启了虚拟化hyper-v&#xff0c;关闭即可。 打开cmd&#xff08;…...

跟着NatureMetabolism学作图:R语言ggplot2转录组差异表达火山图

论文 Independent phenotypic plasticity axes define distinct obesity sub-types https://www.nature.com/articles/s42255-022-00629-2#Sec15 s42255-022-00629-2.pdf 论文中没有公开代码&#xff0c;但是所有作图数据都公开了&#xff0c;我们可以试着用论文中提供的数据…...

Linux进程与线程的内核实现

进程描述符task_struct 进程描述符&#xff08;struct task_struct&#xff09;pid与tgid进程id编号分配规则内存管理mm_struct进程与文件,文件系统 进程,线程创建的本质 clone函数原型线程创建的实现进程创建的实现 总结 进程描述符task_struct 进程描述符&#xff08;st…...

Flink学习之旅:(四)Flink转换算子(Transformation)

1.基本转换算子 基本转换算子说明映射&#xff08;map&#xff09;将数据流中的数据进行转换&#xff0c;形成新的数据流过滤&#xff08;filter&#xff09;将数据流中的数据根据条件过滤扁平映射&#xff08;flatMap&#xff09;将数据流中的整体&#xff08;如&#xff1a;集…...

CesiumJS 中绘制大多边形

本文翻译自Cesium官方&#xff0c;有改动。 本文中提及到的“大多边形”就如下图所示。 在Cesium的早期版本和一些引擎中&#xff0c;我们绘制这种跨度比较大的多边形&#xff0c;经常会看到一些奇怪的冲突问题&#xff0c;如下图所示。 要渲染任何几何体&#xff0c;我们必…...

FreeRTOS移植以及任务

FreeRTOS移植 1.在sys.h中需要把SYSTEM_SUPPORT_OS 改为 1&#xff0c;支持我们使用 FreeRTOS //0,不支持 os //1,支持 os #define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持 OS2.出现报错 …\SYSTEM\usart\usart.c(6): error: #5: cannot open source input file “incl…...

笙默考试管理系统-MyExamTest----codemirror(41)

笙默考试管理系统-MyExamTest----codemirror&#xff08;40&#xff09; 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试…...

C#数据结构--数组和ArrayList

目录 本章目录&#xff1a; 2.1 数组基本概念 2.1.1 数组的声明和初始化 2.1.2 数组元素的设置和存取访问 2.1.4 多维数组 2.1.5 参数数组 2.2ArrayList 类 2.2.1ArrayList 类的成员 2.2.2 应用 ArrayList 类 数组和ArrayList之间的区别以及使用的场景 数组&#xf…...

Stable Diffusion WebUI扩展adetailer安装及功能介绍

ADetailer是Stable Diffusion WebUI的一个扩展,类似于检测细节器。 目录 安装地址 如何安装 1. Windows系统 (1)手动安装 (2)一体机...

Linux安装MINIO

MINIO简介MINIO目录 mkdir -p /opt/minio/data && cd /opt/minio MINIO下载 wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio MINIO授权 chmod x minio MINIO端口 firewall-cmd --zonepublic --add-port7171/tcp --permanent && firewal…...

Java架构师分布式搜索架构

目录 1 导学1.1 初识Elasticsearch1.1.1 Elasticsearch的作用1.1.2 ELK技术栈1.1.3 Elasticsearch和lucene1.1.4.为什么不是其他搜索技术?1.1.5.总结2 Elasticsearch快速建立知识体系3 Elasticsearch和MySQL实体建立联系3.1.mapping映射属性3.2 数据分组聚合3.2.1.聚合的种类3…...

简单宿舍管理系统(springboot+vue)

简单宿舍管理系统&#xff08;springbootvue&#xff09; 1.创建项目1.前端2.数据库3.后端 2.登陆1.前端1.准备工作2.登陆组件3.配置 2.后端1.链接数据库2.创建用户实体类3.数据操作持久层1.配置2.内容3.测试 4.中间业务层1.异常2.业务实现3.测试 5.响应前端控制层 3.前后对接4…...

Socks5代理、IP代理的关键作用

Socks5代理与SK5代理&#xff1a;网络安全的卫士 Socks5代理作为一项先进的代理协议&#xff0c;其多协议支持、身份验证功能以及UDP支持使其成为网络安全的重要支持者。 IP代理&#xff1a;隐私保护与无限访问的利器 IP代理技术通过隐藏真实IP地址&#xff0c;保护用户隐私…...

前端 CSS 经典:box-shadow

1. 基础属性 /* box-shadow: h-shadow v-shadow blur spread color inset; */ box-shadow: 10px 10px 2px 2px red inset; h-shadow: 必填&#xff0c;水平阴影的位置&#xff0c;允许负值 v-shadow: 必填&#xff0c;垂直阴影的位置&#xff0c;允许负值 blur: 可选&#xff…...

使用数组方法打印出 1 - 10000 之间的所有对称数。例如:121、1331等

&#xff08;我从别的人那复制的&#xff0c;原文章请点击此处&#xff09; 源代码&#xff1a; function getNum (start, end) {var arr [];for(var i start; i < end; i) {if (i.toString() i.toString().split().reverse().join() && i.toString().length &…...

DELM深度极限学习机回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Spark大数据分析与实战笔记(第一章 Scala语言基础-5)

文章目录 每日一句正能量章节概要1.5 Scala的模式匹配与样例类1.5.1 模式匹配字符匹配匹配字符串守卫匹配类型匹配数组、元组、集合 1.5.2 样例类 课外补充偏函数 每日一句正能量 “成功的秘诀&#xff0c;在于对目标的执着追求。”——爱迪生 无论是在工作、学习、还是生活中&…...

shell学习脚本04(小滴课堂)

他就可以直接读出来了。不需要在sh后面加参数。 可以用-s隐藏内容&#xff1a; 可以用-t进行指定几秒后显示。 -n限制内容长度。 输入到长度为5自动打印。 我们把-s放到-p后面的话&#xff1a; 这样会出错。 如果最后加5m会一直闪烁。 大家可以按照需求自行使用。...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...