Qt:信号和槽
目录
关于信号
connect函数
关于connect
connect的使用
自定义信号、自定义槽
自定义槽
第一种方式自定义槽
第二种方式自定义槽
自定义信号
信号槽
带参数的信号槽
参数个数一致的示例
参数个数不一致的示例
Q_OBJECT
信号和槽存在的意义
disconnect函数
使用lambda表达式定义槽函数
关于信号
关于信号在 Linux 中也学过信号的概念,Qt中的信号与 Linux 中的信号是不同的概念,但是也是有相似之处的
Qt 中,谈到信号,也是涉及到三个要素:
①信号源
由哪个控件发出的信号
②信号的类型
用户进行不同的操作,就可能触发不同的信号,例如:
点击按钮,触发点击信号
在输入框中移动光标,触发移动光标的信号
勾选一个复选框、选择一个下拉框都会触发出不同的信号
③信号的处理方式
槽(slot) => 函数
Qt 中可以使用 connect 这样的函数,把 一个信号和一个槽 关联起来,后续只要信号触发了,Qt 就会自动的执行槽函数
所谓的"槽函数"本质上也是一种"回调函数"(callback)
Qt 中一定是先关联好 信号和槽,然后再触发这个信号,顺序不能颠倒,否则信号就不知道如何处理了
connect函数
这个函数和 Linux TCP socket 中建立连接的函数,没有任何关系,只是名字恰巧一样
关于connect
connect函数是 QObject 提供的静态的成员函数,Qt 中提供的这些类,本身是存在一定的继承关系的:
QObject 就是其他 Qt 内置类的 祖宗
正是因为 connect函数 是 QObject 提供的,而其他的类都是继承自 QObject 的,所以其他的类也可以使用 connect函数
connect的使用
connect函数的声明:
connect (const QObject *sender, const char * signal ,const QObject * receiver , const char * method , Qt::ConnectionType type = Qt::AutoConnection )
上述的 connect函数 总共有5个参数,但是第5个参数提供了一个默认参数,所以我们可以暂时不考虑,大部分情况下使用的前面4个参数
-
参数1 sender:描述了当前信号是哪个控件发出来的
-
参数2 signal:发送的信号类型
-
参数3 receiver:哪个对象(控件)负责处理这个信号
-
参数4 method:这个对象怎么处理(要处理信号的对象提供的成员函数,槽函数)
下面是简单的示例,界面上包含一个按钮,用户点击按钮,则关闭窗口:在使用QPushButton时,传入第二个参数时,有两个提示,一个是click,另一个是 clicked
click:是一个 slot 函数,作用就是在调用的时候相当于点击了一下按钮
clicked:是过去分词形式,表示点完了才会触发点击信号
我们使用的是clicked,表示点击按钮再触发点击信号
connect 要求,第一个和第二个参数是匹配的,button 的类型如果是 QPushButton*
那么第二个参数的信号必须是 QPushButton 内置的信号(或是QPushButton 父类的信号),不能是一个其他的类,比如 QLineEdit 的信号
close 是 QWidget 内置的槽函数,Widget 继承自 QWidget,也就继承了父亲的槽函数
close 槽函数功能已经是人家内部实现好了,不需要咱们去关心
close 槽函数具体的作用就是:关闭当前的窗口/控件
widget.cpp实现如下:

此时运行项目:

此时点击这个按钮就会关闭窗口了
我们是怎么得知QPushButton中有clicked函数,Widget中有close函数的?
很简单,查看文档即可,如果在当前类中没有找到,那就在当前类的父类中寻找
还有一个问题,下面是我们在代码中使用的connect函数:
connect(button, &QPushButton::clicked, this, &Widget::close);
但是我们看connect的函数声明中,前4个参数的类型如下:
connect (const QObject *sender, const char * signal ,const QObject * receiver , const char * method )
其中第一个和第三个类型是 QObject* 的,我们传入的 button 和 this 都是 QObject 的子类的指针,能够理解
但是第二个和第四个参数,声明中是 char* 的,但是我们传入的是 &QPushButton::clicked 和 &Widget::close,这两个是函数指针,并不是 char* 类型,这是为什么呢?
其实这个函数声明,是以前版本的 Qt 的 connect 函数的声明,以前版本中,传参的写法和现在其实也是有区别的,以前的版本中:
给信号参数传参时,要搭配一个 SIGNAL 宏
给槽参数传参,搭配一个 SLOT 宏,也就是下面的这种形式:
connect(button, SIGNAL(&QPushButton::clicked), this, SLOT(&Widget::close));
从 Qt 5 开始,对上述写法做出了简化,不再需要写 SIGNAL 和 SLOT 宏了
给 connect 提供了重载版本,重载版本中,第二个参数和第四个参数成了 泛型参数,允许传入任意类型的函数指针

此时 connect 函数就带有了一定的 参数检査 功能
如果传入的第一个参数和第二个参数不匹配,或者第三个参数和第四个参数不匹配,此时代码编译出错
不匹配指的是:2/4 参数的函数指针,不是 1/3 参数的成员函数
自定义信号、自定义槽
在刚刚使用 connect函数 时,传入的 clicked 和 close 都是 Qt 内置的,但是内置的信号和槽不一定可以满足我们的要求,所以我们需要自定义信号和自定义槽
自定义槽
slot(槽) 其实就是一个普通的成员函数
自定义一个槽函数,操作过程和自定义一个普通的成员函数没啥区别
下面实现一个自定义的槽函数,在点击按钮后,就执行我们自己实现的槽函数 handleCilcked
在以前的 Qt 的旧版本中,自定义槽函数必须要写在 private/protected/public slots: 下面,后面的新版本就不需要这样了
slots 是 Qt 自己扩展出来的关键字
第一种方式自定义槽
widget.h 中声明:

widget.cpp 中定义:

此时运行程序:

点击按钮:

第二种方式自定义槽
使用图形化界面的方式,先将按钮拖到界面上:

右键按钮,点击转到槽:

这个窗口会列出 QPushButton 中给我们提供的所有的信号
还包含了 QPushButton 父类的信号:
-
QPushButton 继承自 QAbstractButton
-
QAbstractButton 继承自 QWidget
-
QWidget 继承自 QObject
所以下面将这几个父类的信号都列举出来了

选择 clicked,再点击OK,此时在 widget.h 和 widget.cpp 中就有了声明和定义,此时在该函数的内部编写函数的代码即可:


依旧是实现刚刚的功能:

此时运行程序:

点击按钮:

我们发现上述的第二种方式,并没有使用 connect函数:
在 Qt 中,除了通过 connect 来连接信号和槽之外,还可以通过函数名字的方式来自动连接

当函数名符合上述规则之后,Qt 就能自动的把信号和槽给建立上联系
Qt 中调用 connectSlotByName函数 的时候,就会触发上述自动连接信号槽的规则
connectSlotByName函数 正是在自动生成的 ui widget.h 中调用的
-
如果我们通过图形化界面创建控件,还是推荐使用这种快速的方式来连接信号槽
-
如果我们是通过代码的方式来创建控件,还是得手动 connect,因为你的代码中没有调用 connectSlotsByName函数
自定义信号
Qt 中也允许自定义信号
自定义槽函数是非常关键的,开发中大部分情况都是需要自定义槽函数的
槽函数:就是用户触发某个操作之后要进行的业务逻辑
自定义信号比较少见,实际开发中很少会需要自定义信号,信号就对应到用户的某个操作
在 GUI 中,用户能够进行哪些操作,是可以穷举的
Qt 内置的信号,基本上已经覆盖到了上述所有可能的用户操作
因此,使用 Qt 内置的信号,就足以应付大部分的开发场景了
所以这里的自定义信号只需简单了解即可
信号是一类非常特殊的函数
程序员只要写出函数声明,并且告诉 Qt,这是一个"信号"即可
这个函数的定义是 Qt 在编译过程中,自动生成的
自动生成的过程, 程序员无法干预,原因是:
信号在 Qt 中是特殊的机制,Qt 生成的信号函数的实现,要配合 Qt 框架做很多既定的操作
作为信号函数,这个函数的返回值必须是 void
有没有参数都可以,甚至也可以支持重载
signals 也是 Qt 自己扩展出来的关键字
qmake 的时候,调用一些代码的分析/生成工具,扫描到类中包含 signaks 这个关键字的时候,就会自动的把下面的函数声明认为是信号,并且给这些信号函数自动的生成函数定义
所以我们先在 widget.h 中声明自定义的信号函数 mySignal,和自定义槽函数 handleClicked :

widget.cpp中:

此时运行,发现窗口的标题并没有任何的改变,是因为我们这里只是使用 connect 建立连接了,并没有发出信号
如何才能触发出自定义的信号呢?
Qt 内置的信号,都不需要我们手动通过代码来触发,用户在 GUI 进行某些操作时,就会自动触发对应信号,例如 clicked 操作就是 点击按钮 后触发(发射信号的代码已经内置到 Qt 框架中了)
自定义类型的信号,就需要关键字 emit(发射) + 信号函数,就可以触发自定义的信号了
所以新增一行代码:

运行结果:
也就是当我们启动程序后,窗口启动好以后,信号就发送出来了,下面的槽函数就会进行触发
我们也可以不选择在构造函数中发送信号,可以选择点击按钮时再发送信号,所以采用 图形化 的方式,拖动一个按钮到界面上,再右键点击 转到槽:

点击 clicked,再点击 OK:

这里将发送信号的代码写到 on_pushButton_clicked函数 中:

此时运行程序:
点击 发送信号 按钮:

下面梳理一下代码的逻辑:
-
点击按钮,相当于按钮发送了一个 clicked 信号
-
clicked 信号关联到 on_pushButton_clicked槽函数
-
on_pushButton_clicked槽函数 执行又发送了 mySignal信号
-
mySignal信号 又会关联到 handleClicked槽函数
-
所以就会执行 handleClicked槽函数 中改变窗口标题的设置

其实在 Qt 5 中 emit 现在啥都没做,真正的操作都包含在 mySignal 内部生成的函数定义了
所以即使不写 emit,信号也能发送出去,但是还是建议加上 emit,可读性更强,能更明显的表示出什么地方是发射自定义信号
emit除了发射自定义信号,Qt内置的信号也能借助 emit 发射出来
信号槽
带参数的信号槽
我们刚刚所写的 信号和槽函数 都是没有参数的,但是 信号和槽函数 其实也是可以带参数的
当信号带有参数的时候,槽的参数必须和信号的参数一致
类型必须一致,参数个数可以不一致
此时发射信号的时候,就可以给信号函数传递实参,与之对应的这个参数就会被传递到对应的槽函数中,此时就可以起到让信号给槽传参的效果
参数个数一致的示例
我们将 widget.h 中自定义的 信号和槽函数 都加上一个相同的参数:

widget.cpp 中:

在发送信号时,信号中带的实参,就会被传递到槽函数对应的形参中,这样就完成了通过信号给槽传参的效果
此时运行程序:

点击按钮:

传参可以起到复用代码的效果
有多个逻辑,逻辑上整体一致,但是涉及到的数据不同,就可以通过函数-参数来复用代码,并且在不同的场景中传入不同的参数即可
如下所示,使用 图形化 的方式创建两个按钮,并分别右键点击 转到槽:

这两个槽函数分别传入 发送文本1 和 发送文本2 这两个信息:

运行程序:

点击第一个按钮:

点击第二个按钮:

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

参数个数不一致的示例
此时在 widget.h 中,将信号参数多加一个,槽的参数保持不变:
在 widget.cpp 中,给信号传参时也加上第二个参数:
此时虽然槽函数只有一个参数,但是不影响程序的正确运行,和上述执行的情况是一样的
-
信号函数的参数个数,超过了槽函数的参数个数,此时都是可以正常使用的
-
信号函数的参数个数,少于槽函数的参数个数,此时代码无法编译通过
为什么不要求信号的参数个数和槽的参数个数严格一致,此处为什么允许信号的参数比槽的参数多呢?
因为一个槽函数,有可能会绑定多个信号
如果我们严格要求参数个数一致,就意味着信号绑定到槽的要求就变高了,换而言之
当下这样的规则,就允许信号和槽之间的绑定更灵活了,更多的信号可以绑定到这个槽函数上了
当个数不一致时,槽函数就会按照参数顺序,拿到信号的前 N 个参数
至少需要确保,槽函数的每个参数都是有值的
所以要求信号给槽的参数,可以有富裕,但是不能少
Q_OBJECT
Qt 中如果要让某个类能够使用信号槽,也就是可以在类中定义信号和槽函数,则必须要在类最开始的地方,写下 Q_OBJECT宏
这个宏能展开成很多额外的代码,Alt + 鼠标左键,点开 Q_OBJECT:
可以看到包含了这么多代码,并且这些代码还有大量的宏定义,所以还可以进一步展开,会得到一系列很复杂的代码,这些代码就涉及到 Qt 实现的内部原理了(此处就不去深入研究了)
例如在上述实现的代码中,查看 widget.h:

可以看到在最开始的地方就有 Q_OBJECT 这个宏,如果我们将这个宏注释掉,就会报错:
此时这个错误就明确说了,这个类缺少了 Q_OBJECT 这个宏
信号和槽存在的意义
所谓的信号槽,终究要解决的问题,就是响应用户的操作
而其他 GUI,例如前端页面,在响应用户操作时,每一个用户的操作都对应一个处理函数,不需要搞一个 单独的 connect 完成上述的信号槽连接
Qt 信号槽,connect 这个机制,设想很美好的:
-
解耦合. 把触发 用户操作的控件 和 处理对应用户的操作逻辑 解耦合
-
"多对多"效果 一个信号, 可以 connect 到多个槽函数上 一个槽函数,也可以被多个信号 connect
所以前端开发的机制,是完成一对一的:
一个事件只能对应一个处理函数,一个处理函数也只能对应到一个事件上
而 Qt 的机制,所期望的效果是完成多对多的,多对多这个概念在数据库中也是经常遇到的
如下所示,创建三个信号函数和三个槽函数:

此时就可以在 widget.cpp 中进行多对多的connect了:

综上所述,Qt 引入信号槽机制,最本质的目的就是:为了能够让信号和槽之间按照 "多对多" 的方式来进行关联
其他的 GUI框架往往也不具备这样的特性
实际上,随着程序开发这个事情大家经验越来越多,其实在 GUI 开发的过程中,"多对多"这件事其实是个"伪需求
实际开发很少会用到,绝大部分情况一对一就够用了
disconnect函数
使用 disconnect 来断开信号槽的连接,disconnect 使用的方式和 connect 是非常类似的
disconnect用的比较少,大部分的情况下,把信号和槽连上了之后就不必管了
主动断开往往是把信号重新绑定到另一个槽函数上
下面先创建一个按钮:

并绑定自定义的槽函数(采用connect的方式):

此时再创建第二个按钮,使用右键点击转到槽的方式,连接信号和槽

第二个按钮中会先断开 pushButton 原来的信号槽,再重新绑定信号槽

并且在两个槽函数 handleClick 和 handleClick2 中,都加入了日志信息 qDebug(),可以清楚看到发出信号后,是否调用了槽函数
运行程序:

点击第一个按钮,表示调用了 handleClick函数:

再点击第二个按钮后,点击第一个按钮,表示只调用了 handleClick2函数:

如果将这里的 disconnect 注释掉,此时 clicked 这个信号就会同时绑定两个 槽函数:

此时先点击第一个按钮:
点击完第二个按钮后,再点击第一个按钮:
观察结果可以看到,如果没有 disconnect,就会构成一个信号绑定了两个槽函数。触发信号的时候,两个槽函数都会执行
所以就证明了 Qt 的信号槽是支持多对多的,如果只是重新connect,那么新的槽函数不会去替换原来的槽函数,除非 手动 disconnect 才会解除原来绑定的关系
使用lambda表达式定义槽函数
lambda表达式,本质就是一个"匿名函数",主要应用在"回调函数"场景中,是一次性使用的

运行程序:

点击按钮:

此时就完成了功能,使用 lambda表达式,相比于前面自定义槽函数,需要声明和定义,更为简便
后续如果我们对应的槽函数比较简单,而且是一次性使用的,就经常会写作这种 lambda 的形式
lambda 语法是 C++ 11 中引入的,对于 Qt 5 及其更高版本,默认就是按照 C++ 11 来编译的
如果使用 Qt 4 或者更老的版本,就需要手动在 .pro 文件中加上 C++11 的编译选项
下面是当前版本的 .pro 文件中关于 C++11 的编译选项:

信号槽相关知识到此结束
相关文章:
Qt:信号和槽
目录 关于信号 connect函数 关于connect connect的使用 自定义信号、自定义槽 自定义槽 第一种方式自定义槽 第二种方式自定义槽 自定义信号 信号槽 带参数的信号槽 参数个数一致的示例 参数个数不一致的示例 Q_OBJECT 信号和槽存在的意义 disconnect函数 使用…...
可以免费商用的字体下载
这里介绍一个开源仓库,收录的可以免费商用的字体,目前中文字体1308款,英文字体980款,共约2288多款字体。 Description Free fonts that can be used commercially.There are currently 1308 Chinese fonts and 980 English font…...
centos7之LVS-TUNNEL模式
介绍 优缺点以及适用场景 优点:能负载更多的Realserver减轻LB的压力。LVS和Realserver可以不再同一网段。 缺点:tun模式的开销比较大(出口流量大),性能不如DR模式。不支持端口转发。后端Realserver系统必须支持tunnel协议。 适用ÿ…...
Linux驱动开发(3):字符设备驱动
上一章节我们了解到什么是内核模块,模块的加载卸载详细过程以及内核模块的使用等内容。 本章,我们将学习驱动相关的概念,理解字符设备驱动程序的基本框架,并从源码上分析字符设备驱动实现和管理。 主要内容有如下五点:…...
刘艳兵-DBA023-控制文件是Oracle 数据库用来查找数据库文件,控制文件包含以下哪些信息:
控制文件是Oracle 数据库用来查找数据库文件,控制文件包含以下哪些信息: A 表空间信息 B 创建数据库的时间戳 C 有关数据文件、 联机重做日志文件、和归档重做日志文件的信息 D 数据库名称和数据库唯一标识符(DBID) E RMAN备份…...
Vue Scoped CSS深度解析:原理、误区与最佳实践
引言 在Vue开发中,Scoped CSS是一个强大而复杂的功能。它允许我们将样式限制在特定组件内,但同时也带来了一些细微的行为,可能导致意外的样式"泄漏"。本文将深入探讨Vue Scoped CSS的工作原理,解释常见的误区ÿ…...
744. 寻找比目标字母大的最小字母
目录 题目解法一解法二如何比较字符串letters.back()*upper_bound为什么要加* 题目 给你一个字符数组 letters,该数组按非递减顺序排序,以及一个字符 target。letters 里至少有两个不同的字符。 返回 letters 中大于 target 的最小的字符。如果不存在这…...
浅谈QT中Tab键的切换逻辑
浅谈QT中Tab键的切换逻辑 无意中发现在输入界面中按下Tab键时,没有按照预想的顺序切换焦点事件,如下图所示 这个现象还是很有趣,仔细观察了下,默认的切换顺序是按照控件拖入顺序,那么知道了这个问题想要解决起来就很简…...
基于MoviNet检测视频中危险暴力行为
项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【Faster & Mask R-CNN模型实现啤酒瓶瑕疵检测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生…...
《等保测评:抵御网络威胁的盾牌》
在网络空间的无垠战场上,网络安全威胁如同暗夜之狼,潜伏在每一个角落,随时准备对企业和个人发动致命一击。在这场没有硝烟的战争中,等保测评作为国家网络安全等级保护制度的重要组成部分,犹如坚固的盾牌,为…...
前端必知必会-JavaScript 对象属性
文章目录 JavaScript 对象属性访问 JavaScript 属性添加新属性删除属性嵌套对象 总结 JavaScript 对象属性 对象是无序的属性集合 属性是 JavaScript 对象中最重要的部分。 属性可以更改、添加、删除,有些属性是只读的。 访问 JavaScript 属性 访问对象属性的语…...
双11都有什么值得入手的好物?双十一最建议买的5样东西
双11的脚步逐步渐近,我们点开各大电商平台也可以看到,各个商家已经开始大激烈的促销大战,那么双十一作为一年之中最盛大的购物节,都有什么值得入手的好物呢?今天就给大家建议买的5样东西,从家电好物到生活用…...
Xcode 15.4 运行flutter项目,看不到报错信息详情?
Xcode升级后,遇到了奇怪的事情: 运行flutter项目,左侧栏显示有报错信息,但是点击并没有跳转出具体的error详情。【之前都会自己跳转出来的,升级后真的是无厘头】 方案: 点击左侧导航栏最右边的图标——>…...
AMD开始为基于RDNA的GPU开发自己的神经超采样和去噪技术
NVIDIA 的升级技术已经取得了长足的进步,这些技术解决了现代游戏在开启光线追踪时在苛刻场景中的性能问题。NVIDIA 开始实施各种光线追踪和升级技术后,AMD 和英特尔也紧随其后,推出了自己的 FSR 和 XeSS 升级方法。据报道,AMD 将跟…...
Python中的文件I/O操作
在Python编程中,文件I/O(输入/输出)是一个重要的主题,涉及如何读取和写入文件。无论是处理文本文件还是二进制文件,Python提供了简洁易用的接口。本文将介绍如何在Python中进行文件I/O操作,包括读取、写入和…...
.net framework 3.5sp1开启错误进度条不动如何解决
浏览器地址栏输入www.dnz9.com远程解决netframework问题 在Windows操作系统上安装或启用.NET Framework 3.5 SP1时,如果遇到进度条不动的问题,可能由多种原因引起。以下是一些可能的解决方案: 1. 使用Windows功能对话框 1.打开“控制面板”。…...
什么影响网站的SEO排名
1.多IP多C段配置:海外站群服务器通常提供多IP多C段配置,这使得网站可以拥有多个独立的IP地址,有效避免同一IP下多个网站之间的关联性问题,降低被搜索引擎认为是站群作弊的风险。通过将不同的内容部署在不同的IP地址和C段上&#x…...
css绘制s型(grid)
在之前有通过flex布局实现了s型布局,是通过截取数组形式循环加载数据 这次使用grid直接加载数据通过css实现 <div id"app"><template v-for"(item,inx) in items"><div class"row"><template v-for"(ite…...
【华为HCIP实战课程二十八】中间到中间系统协议IS-IS邻居关系排错,网络工程师
一、ISIS邻居关系条件 1、同一层次(比如Level-2路由器不能和Level-1路由器形成邻居关系) 2、同一区域(L1必须同一区域) 3、同一网段 R1和R2之间分别配置如下IP地址和掩码: R1 的接口S1/0/0掩码为/24 R2的接口S1/0/0配置成掩码/28: 此时R1和R2依然可以建立ISIS邻居关系…...
Word首行空格不显示空格符号问题
Word段落首行空格设置指南 问题描述 在Word中编辑文档时,有时会遇到段落首行敲击空格键却不显示空格的问题。这通常与Word的自动更正设置有关。 解决方法 要解决此问题,需要调整Word的自动更正设置。具体步骤如下: 打开Word的"自动更…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
