Qt开发③Qt的信号和槽_概念+使用+自定义信号和槽+连接方式

目录

1. 信号和槽概述

1.1 事件和控件

1.2 信号的本质

1.3 槽的本质

2. 信号和槽的使用

2.1 connect 连接信号和槽

2.2 查看内置信号和槽

2.3 Qt Creator 生成信号槽代码

3. 自定义信号和槽

3.1 不带参数的信号和槽

3.2 带参数的信号和槽

4. 信号与槽的连接方式

4.1 一对一

4.2 一对多

4.3 多对一

4.4 多对多

5. 信号与槽的断开

6. Qt4 版本信号与槽的连接

7. Lambda 定义槽函数

7.1 局部变量引入方式 [ ] 

7.2 函数参数 ( )

7.3 选项 Opt

7.4 返回值类型 ->

7.5 函数体 { }

7.6 槽函数使用 Lambda

8. 信号与槽的优缺点

本篇完。


1. 信号和槽概述

1.1 事件和控件

        在 Qt 中,用户和控件的每次交互过程称为一个事件。比如 “用户点击按钮” 是一个事件,“用户关闭窗口” 也是一个事件。每个事件都会发出一个信号,例如用户点击按钮会发出 “按钮被点击” 的信号,用户关闭窗口会发出 “窗口被关闭” 的信号。

        Qt 中的所有控件都具有接收信号的能力,一个控件还可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗口接收到 “按钮被点击” 的信号后,会做出 “关闭自己” 的响应动作;再比如输入框自己接收到 “输入框被点击” 的信号后,会做出 “显示闪烁的光标,等待用户输入数据” 的响应动作。在 Qt 中,对信号做出的响应动作就称之为槽。

        信号和槽是 Qt 特有的消息传输机制,可以通过 connect 这样的函数,把一个信号和一个槽这种相互独立的控件关联起来。比如,“按钮” 和 “窗口” 本身是两个独立的控件,点击 “按钮” 并不会对 “窗口” 造成任何影响。通过信号和槽机制,可以将 “按钮” 和 “窗口” 关联起来,实现 “点击按钮会使窗口关闭” 的效果。


1.2 信号的本质

        信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时 Qt 对应的窗口类会发出某个信号,以此对用户的操作做出反应。因此,信号的本质就是事件。

  • 按钮单击、双击
  • 窗口刷新
  • 鼠标移动、鼠标按下、鼠标释放
  • 键盘输入

那么在 Qt 中信号是通过什么形式呈现给使用者的呢?

  • 我们对哪个窗口进行操作, 哪个窗口就可以捕捉到这些被触发的事件。
  • 对于使用者来说触发了一个事件,我们就可以得到 Qt 框架给我们发出的某个特定信号。

  • 信号的呈现形式就是函数, 也就是说某个事件产生了, Qt 框架就会调用某个对应的信号函数,通知使用者。

在 Qt 中信号的发出者是某个实例化的类对象。


1.3 槽的本质

        槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++ 函数是⼀样的,可以定义在类的任何位置(public、protected 或 private),可以具有任何参数,可以被重载,也可以被直接调用(但是不能有默认参数)。

        槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

所谓的 “槽函数” 本质上也是一种 “回调函数”(callback)。

C 语言阶段 - 函数指针:

  • 实现转移表,降低代码的 “圈复杂度”
  • 实现回调函数效果(qsort)

C++ 阶段:

  • STL 中,函数对象 / 仿函数
  • lambda 表达式

Linux 阶段:

  • 信号处理函数
  • 线程的入口函数
  • epoll 基于回调的机制

信号和槽机制底层是通过函数间的相互调用实现的
        每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。

        例如:“按钮被按下” 这个信号可以用 clicked() 函数表示,“窗口关闭” 这个槽可以用 close() 函数表示,假如使用信号和槽机制 - 实现:“点击按钮会关闭窗口” 的功能,其实就是 clicked() 函数调用 close() 函数的效果。

信号函数和槽函数通常位于某个类中

和普通的成员函数相比,它们的特别之处:

  • 信号函数用 signals 关键字修饰,槽函数用 public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数。
  • 信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

        信号函数的定义是 Qt 自动在编译程序之前生成的,我们编写 Qt 应用程序无需关注这个,这种自动生成代码的机制称为 “ 元编程 ”(Meta Programming),这种操作在很多场景中都能见到。


2. 信号和槽的使用

2.1 connect 连接信号和槽

        在 Qt 中,QObject 类提供了一个静态成员函数 connect() ,该函数专门用来关联指定的信号函数和槽函数。

关于 QObject:

        QObject 是 Qt 内置的父类,Qt 中提供的很多类都是直接或者间接继承自 QObject。(在 Java 中也存在相似的设定)

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,通常不需要手动设定。

代码示例:

在窗口中设置一个按钮,当点击 “按钮” 时关闭 “窗口”:


2.2 查看内置信号和槽

打开帮助文档有三种方式,实际编程中使用哪种都可以。

(1)光标放到要查询的类名 / 方法名上,直接按 F1


(2)Qt Creator 左侧边栏中直接用鼠标单击 “帮助” 按钮。


(3)找到 Qt Creator 的安装路径,在 "bin" 文件夹下找到 assistant.exe,双击打开


        系统自带的信号和槽通常是通过 “Qt 帮助文档” 来查询的。如上述示例,要查询 “按钮” 的信号,在帮助文档中输入:QPushButton

        首先可以在 "Contents" 中寻找关键字 signals,如果没有找到,继续去父类中查找,因此我们去他的父类 QAbstractButton 中继续查找关键字 signals

这里的 clicked() 就是我们要找的信号。槽函数的寻找方式和信号一样,只不过它的关键字是 slot。


2.3 Qt Creator 生成信号槽代码

Qt Creator 可以快速帮助我们生成信号槽相关的代码。

代码示例:在窗口中设置一个按钮,当点击 “按钮” 时关闭 “窗口

(1)新建项目,如下图为新建完成之后所包含的所有文件

注意:创建时要生成 UI 设计文件。

(2)双击 widget.ui 文件,进入 UI 设计界面


(3)在 UI 设计窗口中拖入一个 “按钮”,并且修改 “按钮” 的名称及字体大小等


(4)可视化生成槽函数

        当鼠标单击 “转到槽...” 之后,出现如下界面:对于按钮来说,当点击时发送的信号是:clicked(),所以此处选择:clicked()

这个窗口列出了 QPushButton 给我们提供的所有信号(还包含了 QPushButton 父类的信号)。

        对于普通按钮来说,使用 clicked 信号即可。clicked(bool) 是没有意义的,具有特殊状态的按钮(比如:复选按钮)才会用到 clicked(bool)。


(5)自动生成槽函数原型框架

发现在 "widget.h" 头文件中自动添加了槽函数的声明

自动生成槽函数的名称有一定的规则,槽函数的命名规则为:on_XXX_SSS,其中:

  1. 以 "on" 开头,中间使用下划线连接起来。
  2. "XXX" 表示的是对象名(控件的 objectName 属性)。
  3. "SSS" 表示的是对应的信号

        如:"on_pushButton_clicked() ",pushButton 代表的是对象名,clicked 是对应的信号。按照这种命名风格定义的槽函数,就会被 Qt 自动的和对应的信号进行连接。但是我们日常写代码的时候,除非是 IDE 自动生成,否则最好还是不要去依赖命名规则,而是显式使用 connect 更好。

  • 一方面,显式 connect 可以更清晰直观的描述信号和槽的连接关系。
  • 另一方面,也是防止信号或者槽的名字拼写错误导致连接失效。

        当然,是配置大于约定,还是约定大于配置,哪种更好。这样的话题业界尚存在争议,这里还是更建议优先考虑显式 connect。


发现在 "widget.cpp" 中自动生成槽函数定义  


(6)在槽函数函数定义中添加要实现的功能,实现关闭窗口的效果


3. 自定义信号和槽

3.1 不带参数的信号和槽

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

        Qt 中如果要让某个类能够使用信号槽(可以在类中定义信号和槽函数),则必须要在类最开始的地方写下 Q_OBJECT 宏(这个宏可以展开很多代码)。如果不加上这个宏,那么编译时就会报错。这个宏不需要我们自己手动添加,一般 Qt Creator 会帮我们自动生成。


自定义信号函数书写规范:

自定义信号在实际开发中很少需要用到,Qt 内置的信号就足以应付大部分的开发场景了。

        所谓 Qt 的信号,本质上也就是一个 “函数”,在 Qt 5 以及更高版本中,槽函数和普通的成员函数之间没有什么差别。但是,信号是一类非常特殊的函数,我们只要写出函数声明,并告诉 Qt 这是一个 “信号” 即可。这个函数的定义是 Qt 在编译过程中自动生成的。

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

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


自定义槽函数书写规范:

所谓的自定义一个槽函数,其操作规程和自定义一个普通成员函数没有什么区别。

  1. 早期的 Qt 版本要求槽函数必须写到 "public slots" 下,但是现在高级版本的 Qt 不做要求。
  2. 返回值为 void,需要声明,也需要实现。
  3. 可以有参数,可以发生重载。

槽声明的两种写法: 


        此处的 slots 是 Qt 自己扩展的关键字,不是 C++ 标准中的语法。qmake 构建 Qt 项目时,就会调用专门的扫描器,扫描代码中特定的关键字(比如:slot),基于关键字自动生成一大堆相关代码。

发送信号 :

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


使用示例:

在 widget.h 中声明自定义的信号和槽


在 widget.cpp 中实现槽函数,并且关联信号和槽

        首先关联信号和槽,一旦检测到信号发射之后就会立刻执行关联的槽函数。反之,若先发射信号,此时还没有关联槽函数,当信号发射之后槽函数就不会响应。

在 widget.cpp 中实现槽函数,并且关联信号和槽

        首先关联信号和槽,⼀旦检测到信号发射之后就会立刻执行关联的槽函数。反之,若先发射信号,此时还没有关联槽函数,当信号发射之后槽函数就不会响应。


3.2 带参数的信号和槽

        Qt 的信号和槽也支持带有参数,同时也可以支持重载。要求:信号函数的参数列表要和对应连接的槽函数参数列表一致。(一致主要是要求类型,个数如果不一致也可以,但要求信号的参数个数比槽的参数个数多

        此时信号触发,调用到槽函数的时候,信号函数中的实参就能够被传递到槽函数的形参当中。通过这样的机制就可以让信号给槽传递数据了。

(1)重载信号槽示例

在 "widget.h" 头文件中声明重载的信号函数以及重载的槽函数

在 "Widget.cpp" 文件实现重载槽函数以及连接信号和槽

执行结果:


(2)信号槽参数列表匹配规则示例

在 "widget.h" 头文件中声明信号和槽函数

在 "widget.cpp" 文件中实现槽函数以及连接信号和槽

        其实信号的参数个数可以多于槽函数的参数个数,但是槽的参数个数不能多于信号参数个数。但是实际开发中最好还是保持参数个数也能匹配⼀致。


(3)信号的参数个数多于槽函数的参数个数

在 "widget.h" 头文件中声明信号和槽函数

在 "widget.cpp" 文件中实现槽函数以及连接信号和槽


4. 信号与槽的连接方式

4.1 一对一

主要有两种形式,分别是:

  1. ⼀个信号连接⼀个槽
  2. ⼀个信号连接⼀个信号

一个信号连接一个槽

在 "widget.h" 中声明信号和槽以及信号发射函数:

在 "widget.cpp" 中实现槽函数,信号发射函数以及连接信号和槽:


一个信号连接另一个信号

在上一段代码的基础上,在 "widget.cpp" 文件中添加如下代码:


4.2 一对多

一个信号连接多个槽:

在 "widget.h" 头文件中声明一个信号和三个槽:


4.3 多对一

多个信号连接一个槽函数:

在 "widget.h" 头文件中声明两个信号以及一个槽:


在 "widget.cpp" 文件中实现槽函数以及连接信号和槽:


4.4 多对多

多个信号连接多个槽函数:

在 "widget.h" 头文件中声明三个信号以及三个槽:

在 "widget.cpp" 文件中实现槽函数以及连接信号和槽:

        实际上,随着程序员经验越来越多,在 GUI 开发的过程中,“多对多” 其实是个 “伪需求”,实际开发很少会用到,绝大部分情况来说,“一对一” 就够用了。

信号槽存在的意义:

  • 解耦合(写代码追求 “高内聚,低耦合”)
  • 多对多(非常类似于 MySQL 中的 “多对多”)

5. 信号与槽的断开

使用 disconnect 即可完成断开,disconnect 的用法和 connect 基本一致。

        实际上大部分情况下,把信号和槽连接上之后就不必管了,所以 disconnect 使用的比较少。主动断开往往是把信号重新绑定到另一个槽函数上。


6. Qt4 版本信号与槽的连接

        Qt4 中的 connect 用法和 Qt5 相比更复杂,需要搭配 SIGNAL 和 SLOT 宏来完成,而且缺少必要的函数类型的检查,使代码更容易出错。

在 "widget.h" 头文件中声明信号和槽:

在 "widget.cpp" 文件中实现槽函数以及连接信号与槽:


Qt4 版本信号与槽连接的优缺点:

  • 优点:参数直观。
  • 缺点:参数类型不做检测。

7. Lambda 定义槽函数

        Qt5 在 Qt4 的基础上提高了信号与槽的灵活性,允许使用任意函数作为槽函数。但如果想方便的编写槽函数,比如在编写函数时连函数名都不想定义,则可以通过 Lambda 表达式来达到这个目的。

        Lambda 表达式是 C++11 增加的特性。C++11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。

Lambda 表达式的语法格式如下:

[ capture ] ( params ) opt -> ret { Function body;
};

说明:


7.1 局部变量引入方式 [ ] 

[ ] : 标识一个  Lambda 表达式的开始。不可省略。

说明:

  • 由于使用引用方式捕获对象会有局部变量释放了而 Lambda 函数还没有被调用的情况。如果执行 Lambda函数,那么引用传递方式捕获进来的局部变量的值不可预知。所以绝大多数场合使用的形式为:[=] () { }
  • 早期版本的 Qt,若要使用 Lambda 表达式,要在 ".pro" 文件中添加: CONFIG += C++11 因为 Lambda 表达式是 C++11 标准提出的。Qt5 以上的版本无需手动添加,在新建项目时会自动添加。

Lambda 表达式的使用:

以 [=] 方式传递,外部的所有变量在 Lambda 表达式中都可以使用:

以 [a] 方式传递,在 Lambda 表达式中只能使用传递进来的 a:

        Lambda 表达式除了可以按照值得方式来捕获变量 [=],还可以按照引用得方式来捕获 [&](但 Qt 中很少这样写),捕获到的变量一般就是各自控件得指针。指针变量按照值传递或者引用来传递都无所谓。如果选择按照引用来传递,还得更关注这个引用得变量本身的生命周期。


7.2 函数参数 ( )

        (params) 表示 Lambda函数对象接收的参数,类似于函数定义中的小括号表示函数接收的参数类型和个数。参数可以通过按值(如:(int a,int b))和按引用(如:(int &a,int &b))两种方式进行传递。函数参数部分可以省略,省略后相当于无参的函数。


7.3 选项 Opt

Opt 部分是可选项,最常用的是 mutable 声明,这部分可以省略。

        Lambda 表达式外部的局部变量通过值传递进来时,其默认是 const,所以不能修改这个局部变量的拷贝,加上 mutable 就可以修改。


7.4 返回值类型 ->

        可以指定 Lambda表达式返回值类型。如果不指定返回值类型,则编译器会根据代码实现为函数推导一个返回类型。如果没有返回值,则可忽略此部分。


7.5 函数体 { }

        Lambda 表达式的函数体部分与普通函数体一致。用 { } 标识函数的实现,不能省略,但函数体可以为空。


7.6 槽函数使用 Lambda

点击按钮关闭窗口:


当 "connect" 函数第三个参数为 "this" 时,第四个参数使用 Lambda表达式时,可以省略掉 "this"


8. 信号与槽的优缺点

优点:松散耦合

        信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt 的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject 类。


缺点:效率较低

        与回调函数相比,信号和槽稍微慢一些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约 10 倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组 / 解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。

        一个客户端程序中,最慢的环节往往是 “人”。假设本身基于回调的方式是 10us,使用信号槽的方式是 100us。对于使用程序的人来说,是感知不到的。


本篇完。

下一篇:Qt开发④Qt常用控件_上_QWdget属性+按钮类控件。

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

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

相关文章

【动态路由】系统Web URL资源整合系列(后端技术实现)【apisix实现】

需求说明 软件功能需求:反向代理功能(描述:apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 业务应用等多个web资…

Vue2 中使用 UniApp 时,生命周期钩子函数总结

在 Vue2 中使用 UniApp 时,生命周期钩子函数是一个重要的概念。它允许开发者在特定的时间点运行代码,管理组件的生命周期。以下是 Vue2 中 UniApp 常用的生命周期钩子函数总结: 1. beforeCreate 说明: 组件实例刚被创建,此时数据…

在Ubuntu24.04上安装Stable-Diffusion1.10.1版本

之前曾介绍过在Ubuntu22.04上安装Stable-Diffusion: 在Ubuntu22.04上部署Stable Diffusion_ubuntu stable dif-CSDN博客 这个安装我们使用conda python虚拟机。这次我们介绍的是在Ubuntu24.04安装Stable-Diffusion的最新版本V1.10.1(截止到今天最新版&…

IIS asp.net权限不足

检查应用程序池的权限 IIS 应用程序池默认使用一个低权限账户(如 IIS_IUSRS),这可能导致无法删除某些文件或目录。可以通过以下方式提升权限: 方法 1:修改应用程序池的标识 打开 IIS 管理器。 在左侧导航树中&#x…

MongoDB 常用命令速查表

以下是一份 MongoDB 常用命令速查表&#xff0c;涵盖数据库、集合、文档的增删改查、索引管理、聚合操作等场景&#xff1a; 1. 数据库操作 命令说明show dbs查看所有数据库use <db-name>切换/创建数据库&#xff08;需插入数据后才会显示&#xff09;db.dropDatabase()…

23种设计模式 - 模板方法

模式定义 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;它通过定义算法的骨架&#xff08;固定步骤&#xff09;&#xff0c;允许子类在不改变算法结构的情况下重写特定步骤。该模式的核心是将通用流程封装在基类中&#xff…

使用Java爬虫获取1688自定义API操作接口

在电商领域&#xff0c;1688作为国内领先的B2B平台&#xff0c;提供了丰富的API接口&#xff0c;允许开发者获取商品信息、店铺信息等。其中&#xff0c;custom 接口允许开发者进行自定义操作&#xff0c;获取特定的数据。本文将详细介绍如何使用Java爬虫技术&#xff0c;通过1…

MVTEC数据集笔记

前言 网上的博客只有从论文里摘出的介绍&#xff0c;没有数据集文件详细的样子&#xff0c;下载数据集之后&#xff0c;对数据集具体的构成做一个补充的笔记。 下载链接&#xff1a;https://ai-studio-online.bj.bcebos.com/v1/7d4a3cf558254bbaaf4778ea336cb14ed8bbb96a7f2a…

记一次渗透测试实战之Sightless

信息收集 端口扫描 使用nmap进行端口探测&#xff0c;发现存在21、22、80端口开放。 FTP未授权访问 尝试21端口未授权访问。 目录爆破 使用工具进行爆破目录。 未发现有用的路径&#xff0c;接着尝试访问80端口。 Web网站 访问主页 发现存在一个数据库调用页面 右上角有一…

前端监控的具体实现细节

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【网络安全 | 漏洞挖掘】我如何通过Cookie Manipulation发现主域上的关键PII?

未经许可,不得转载。 文章目录 正文正文 在分析 Example.com 的认证机制时,我注意到一个特定的 cookie,USER_ID,包含了一个具有预测性的会话标识符,其格式为: USER_ID="VYCVCDs-TZBI:XXXX-random-data"其中,XXXX 是由四个大写字母组成的部分,我使用 Burp S…

PostgreSQL 的崛起与无服务器数据库的新时代

根据 2023 年 Stack Overflow 开发人员调查 &#xff0c;PostgreSQL 超越 MySQL 成为最受开发人员推崇和期望的数据库系统&#xff0c;这是一个重要的里程碑。这一转变反映了开发人员社区对 PostgreSQL 强大的功能集、可靠性和可扩展性的日益认同。 这种不断变化的格局激发了数…

计算机视觉+Numpy和OpenCV入门

Day 1&#xff1a;Python基础Numpy和OpenCV入门 Python基础 变量与数据类型、函数与类的定义、列表与字典操作文件读写操作&#xff08;读写图像和数据文件&#xff09; 练习任务&#xff1a;写一个Python脚本&#xff0c;读取一个图像并保存灰度图像。 import cv2 img cv2.im…

cesium基础设置

cesium官网下载&#xff1a;https://cesium.com/downloads/ 1.安装cesium 选择下载到本地使用&#xff0c;或者通过npm下载到项目中 2.代码书写 &#xff08;1&#xff09;创建容器 <div id"cesiumContainer" style"width: 100%; height: 100%"><…

C++ 实践扩展(Qt Creator 联动 Visual Studio 2022)

​ 这里我们将在 VS 上实现 QT 编程&#xff0c;实现如下&#xff1a; 一、Vs 2022 配置&#xff08;若已安装&#xff0c;可直接跳过&#xff09; 点击链接&#xff1a;​​​​​Visual Studio 2022 我们先去 Vs 官网下载&#xff0c;如下&#xff1a; 等待程序安装完成之…

《解锁自然语言处理:让公众正确拥抱AI语言魔法》

在当今数字化浪潮中&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术作为人工智能领域的璀璨明珠&#xff0c;正以惊人的速度融入我们的生活。从智能语音助手到智能客服&#xff0c;从机器翻译到内容创作辅助&#xff0c;NLP技术无处不在。然而&#xff0c;如同任何强…

uniapp webview嵌入外部h5网页后的消息通知

最近开发了个oa系统&#xff0c;pc端的表单使用form-create开发&#xff0c;form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。移动端使用uniapp开发&#xff0c;但是因为form-create移动端只支持vant&#xff0c;不支持uniapp。官…

Python在网络安全中的应用 python与网络安全

前言 网络安全是保护网络、系统和程序免受数字攻击的做法。据估计&#xff0c; 2019 年该行业价值 1120 亿美元&#xff0c;到2021 年估计有 350 万个职位空缺。 许多编程语言用于执行与网络安全相关的日常任务&#xff0c;但其中一种已成为行业标准&#xff1a;Python&#…

设计模式15:中介者模式

系列总链接&#xff1a;《大话设计模式》学习记录_net 大话设计-CSDN博客 1.概述 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为设计模式&#xff0c;旨在通过一个中介对象来封装一系列对象之间的交互方式&#xff0c;从而减少这些对象间的直接依赖。在该模式…

golang常用库之-swaggo/swag根据注释生成接口文档

golang常用库之-swaggo/swag库根据注释生成接口文档 什么是swaggo/swag github&#xff1a;https://github.com/swaggo/swag 参考文档&#xff1a;https://golang.halfiisland.com/community/pkgs/web/swag.html#%E4%BD%BF%E7%94%A8 swaggo/swag 是 Swagger API 2.0 在 go 语…