【Qt】控件的理解 和 基础控件 QWidget 属性详解(通俗易懂+附源码+思维导图框架)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”
绪论:
通过上一章对信号槽的理解相信你对Qt的认识肯定有了很大的进步,下面将通过本篇文章带你深入的认识Widget控件(主窗口),他是很多其他控件的父类,它的很多属性都能运用到其他属性中,所以下面将带你认识Widget的常见的属性并附有大量的练习,包括但不限于Widget 窗口的透明度、控件的能否使用、窗口标题的设置、认识qrc加载图片机制等12个属性。之后将持续更新中常用信号。
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。
控件 Widget
控价通俗来说界面上的各种元素的统称,其中 Qt Designer 中左侧一长条就是Qt内置好的控件,能直接拖拽使用
之前开发GUI没啥控件概念,界面上显示出来的东西,其实都是画出来的,显示器可以理解成 画布
- 开发一个图形化界面的程序,就相当于先画出一个窗口(矩形,如下图)
- 后来控件的概念就被引入,如HTML中的标签(原始的控件:<img>、<a>、…)
- 新的GUI开发体系越来越丰富,控件数量/质量越来越提升了
- Qt 的控件虽然很多,但整体来说,颜值还是比更现代的控件体系要逊色一筹
- 不过近几年Qt Designer Studio 对标现代的界面体系(制作出来界面的美化程度就是业界领先的一档~)
QWidget类
在Qt Creator 右侧,可以看到QWidget的各种属性并且进行编辑
上述属性都可以通过Qt的文档来一一进行了解
其中知道的是:会有很多控件都会继承于QWidget,该控件就能使用父类QWidget中的属性,这样通过了解QWidget中的属性就也能控制器子类控件,所以我们了解QWidget是非常有必要的。
1. enabled 控件是否可用
作用:描述一个控件是否处于 “可用” 状态,反之就是禁用状态
- 所谓 “禁⽤” 指的是该控件不能接收任何⽤⼾的输⼊事件, 并且外观上往往是灰⾊的.
- 如果⼀个 widget 被禁⽤, 则该 widget 的⼦元素也被禁⽤
方法:
- isEnabled:获取到控件的可⽤状态
- setEnabled:设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤
实操:
将一个按钮控件 “禁用”
通过拖拽快速生成两个按钮控件,他们都是继承于QWidget的,所以将属性设置为enabled时就会无法使用:
发现就变白了
创建两个按钮,通过一个按钮去禁用另外一个按钮
拖拽两按钮,对其中一个按钮设置信号槽,当点击该按钮时设置另外一个按钮的enabled状态
注意点:
1.1 objectName 控件名称
objectName 该属性是要保证唯一的,它本质就是一个控件的唯一id
- 当自动生成的objectName有点规律:控件的类型 + 下划线 + 数字
- 但带有数字的命名方式是一个不太好的习惯,所以一般建议再自行修改下,让他有点含义
然后对这两个按钮添加槽函数(右击选择转到槽即可)
其中对于点击选择信号:clicked 来说他有两个版本
- 一个是无参的(没什么好说的)
- 一个是 bool 参数,他是代表着checked当前是否被勾选(类似一种选项框,对于pushbutton是没有意义的)
源码:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}//使用clicked信号设置槽函数
void Widget::on_pushButton_clicked()
{//当点击按钮时,触发该信号槽if( ui->pushButton_2->isEnabled())//当为使用状态时改成禁用{ui->pushButton_2->setEnabled(false);}else{//反之ui->pushButton_2->setEnabled(true);}
}
2. geometry 坐标系
- geometry(英文就是几何)
- 可以把它理解成4个属性的统称或者是一个结构体(QRect类)内部是有 x、y、width、height 四个属性,通过这四个属性就能知道或者设置该控件的位置和大小(如下图)
常用方法:
- 获取位置和尺寸:geometry()
- 返回结果是⼀个 QRect(矩阵),
- 该对象包含了 x, y, width, height 其中 x, y 是左上⻆的坐标
- 再通过
对象.x()
、对象.y() ...
的形式获取具体的值
- 设置控件位置
- 设置控件的位置和尺⼨可以直接设置⼀个 QRect:
setGeometry(QRect)
- 也可以分四个属性单独设置:
setGeometry(int x, int y, int width, int height)
- 设置控件的位置和尺⼨可以直接设置⼀个 QRect:
理解xy坐标(如下图):
实操: 实现(上下左右)方向键 控制移动
实现原理:
- 通过信号槽 + gemotry 方法实现按钮移动
- 通过点击几个按钮,修改target按钮的geometry(几何)
首先创建五个按钮(并注意修改objectName):
生成下面四个按钮的槽函数
- QDebug能打印许多Qt中的新类
打印结果如下:
完善好这4个按钮的槽函数:
但注意的是:
当前代码执行的效果仅仅是修改了调整左上角的位置,此时因为左上角位置改变同时高度和宽度也会同时发送改变(如上图会出现该控件不断的拉伸的情况)源码:
向上的槽函数: void Widget::on_pushButton_up_clicked() {QRect rect = ui->pushButton_vessel->geometry();qDebug() << rect.y();rect.setY(rect.y() - 5);//此处是让y值-5,因为是位置的改变,会导致其他值也发送生改变ui->pushButton_vessel->setGeometry(rect); }
让按钮进行平移(移动)
若想真正的实现平移
也就是不能使用单参数的setGeometry,而是使用setGeometry的另外一个重载进行位置的修改,同时在改变某个值的同时保证另外几个值不变(setGeometry(int x, int y, int width, int height)
)
槽函数源码如下:
void Widget::on_pushButton_up_clicked()
{QRect rect = ui->pushButton_vessel->geometry();qDebug() << rect.y();ui->pushButton_vessel->setGeometry(rect.x(),rect.y() - 5,rect.width(),rect.height());
}void Widget::on_pushButton_left_clicked()
{QRect rect = ui->pushButton_vessel->geometry();qDebug() << rect.x();ui->pushButton_vessel->setGeometry(rect.x() - 5,rect.y(),rect.width(),rect.height());
}void Widget::on_pushButton_down_clicked()
{QRect rect = ui->pushButton_vessel->geometry();qDebug() << rect.y();ui->pushButton_vessel->setGeometry(rect.x(),rect.y() + 5,rect.width(),rect.height());
}void Widget::on_pushButton_right_clicked()
{QRect rect = ui->pushButton_vessel->geometry();qDebug() << rect.y();ui->pushButton_vessel->setGeometry(rect.x()+ 5,rect.y(),rect.width(),rect.height());
}
3. Window Frame 的影响
Windows frame 窗口框架(操作系统自带的),如果 widget 作为⼀个窗⼝ (带有标题栏, 最⼩化, 最⼤化, 关闭按钮), 那么在计算尺⼨和坐标的时候就有两种算法:
- 包含 window frame
- 不包含 window frame.
可以理解成游戏的全屏和非全屏模式,或者是否带有标题栏
在Qt中,关于位置尺寸,提供了许多API,即可以以Widget本题左上角原地的(不包含Windowsframe),也可以以 window frame左上角为原点
实操:geometry 和 frameGeometry 两种方法来移动位置
当代码在构造函数中时,widget对象正在构造,还没有被加入到window frame中
因此若在构造函数中查看他们的位置就看不到,就需要通过一些控件,并在槽函数中打印查看
- window frame 就可以看成最顶上的那一条
4. windTitle 窗口标题
当前 windowTitle 属性,是从属于 QWidget
- 获取到控件的窗⼝标题:windowTitle()
- 设置控件的窗⼝标题:setWindowTitle(const QString& title)
-
windowTitle属性的设置只针对顶层窗口这样的QWidget才有效
-
当前不应该给按钮设置windowTiltle,但是实际设计好了之后没生效,也没报错(这是不太科学的)
-
这一点,更希望代码写出不科学时,能够给一些报错提示
5. windowIcon 设置窗口的图标
windowIcon 的 默认图标(发现比较丑,一般情况下也是需要自己设定的):
- 获取到控件的窗⼝图标:windowIcon() 返回 QIcon 对象
- 设置控件的窗⼝图标. :setWindowIcon(const QIcon& icon)
这个api类似 windowTitle 也是只能针对顶层窗口 使用
- 先准备一个图片
- 创建一个QIcon对象,其中在栈上创建对象(对于QIcon是一个比较小的对象,目的就是为了设置某个 QWidget 对象中的图片,QIcon对象释不释放都不影响)
- 构造时,添加路径
- 路径不要带中文
- 路径中使用
\\
作为路径分隔符,因为C语言中\
是转义字符 - 但更推荐使用
/
来代替(或者使用 C++11 中的字符串原始字面量r ("....")
) - 其中注意的是,使用绝对路径引入图片是不科学的,因为你无法确保开发机上图片的路径和用户电脑上图片的路径完全一致,所以尽量使用相对路径
C++11 R保持原始字符串:
通过 \\
将 \
表示为不使用转义字符
使用 /
代替 \
:
但相对路径也有一定的缺陷就是,用户仍然可能就将图片文件删除或更改,所以引入qrc机制:
6. qrc 机制:
这个机制就是从根本上解决上述两个问题
- 确保你的图片在路径目标用户机上存在
- 确保你的图片不会被用户搞没了
给 Qt 项目引入一个额外xml文件(后缀名使用 .qrc 表示)
在这个 xml 中把要使用的图片资源给导入进来,并且在xml中进行记录
Qt 在编译项目的时候,就会根据 qrc 中描述的图片信息,找到图片内容,提取图片的二进制数据,把这些二进制数据转换成 C++ 代码,最终编译到exe里!
但缺点也很明显,无法导入太大的资源文件
qrc 添加图片机制流程:
-
创建 qrc文件
-
把图片导入qrc文件中
将要加载的图片存放到项目目录下:
- 先创建一个前缀(Prefix):虚拟目录(这个目录并不在电脑真实存在,是在Qt中抽象出来的),为了方便Qt代码中访问到这个图片。
- 然后把使用的图片给导入 资源文件 中(点击Add Files选择图片),导入图片需要确保图片在 resource.qrc 同级目录下/同级目录的子目录里(需要拷贝进来)
- 再次通过QIcon对象获取该路径即可,此时需要访问的就是qrc中管理的文件路径,并且注意需要在路径上带有
:
前缀
- 运行后就会自动生成 qrc_resource.cpp (resource是自己取的qrc文件名称),也就是会将图片的每个字节存储起来,当Qt项目进行编译的时候,这个cpp文件机会被编译到一个exe文件中,所以上述图片的数据也就被加载到内存中了
- 先创建一个前缀(Prefix):虚拟目录(这个目录并不在电脑真实存在,是在Qt中抽象出来的),为了方便Qt代码中访问到这个图片。
7. windowOpacity 半透明效果
例如毛玻璃效果(基于半透明在做一些处理)
- 获取到控件的不透明数值:
windowOpacity()
- 返回 float,
- 取值为 0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表⽰完全不透明
- 注意的是:数值越大越不透明~
- 设置控件的不透明数值:
setWindowOpacity(float n)
实操:设置窗口的透明度
通过两个按钮(+、-)的槽函数设置透明度
- 拖拽上两个按钮,修改ObjectName Add Sub
- 给两个按钮添加槽函数,内部修改整个窗口的透明度
- 通过windowOpacoity获取主窗口的opacity对象,调整opacity对象的透明度值(+= 0.1 / -= 0.1)
- 打印情况opacity的值
- 给主窗口设置透明度,通过this指针调用seyWindowOpacity
void Widget::on_pushButton_plus_clicked()
{float opacity = this->windowOpacity();this->setWindowOpacity(opacity + 0.1);
}void Widget::on_pushButton_sub_clicked()
{float opacity = this->windowOpacity();this->setWindowOpacity(opacity - 0.1);
}
当我们查看 opacity 的值时不难发现,变化是不精准的:
其中发现窗口的不透明度,变化并非精确的(因为IEEE 754标准规定浮点数要使用二进制科学计数法的方式来表示)
原因也很简单:
也是c/c++中float和double 类型的缺陷,因为它们的有效数部分长度是有效的,所以无法凑出一个非常接近0.1这样的数(但优点:运算速度快,占用空间小)
- 所以说不能把两个浮点数直接比较!!
- 那么解决办法是 通过作差的方法,判断绝对值,看他是否小于预期误差范围~
防御性编程:
透明度值只能在 0 ~ 1.0 区间,当超过 0 ~ 1.0 的值都无法设置进去- 虽然不判定条件也ok,但还是建议加上
- 虽然不判定条件也ok,但还是建议加上
8. cursor 光标的设置
API | 说明 |
---|---|
cursor() | 获取到当前 widget 的 cursor 属性, 返回 QCursor 对象. 当⿏标悬停在该 widget 上时, 就会显⽰出对应的形状. |
setCursor(const QCursor& cursor) | 设置该 widget 光标的形状. 仅在⿏标停留在该 widget 上时⽣效. |
QGuiApplication::setOverrideCursor(const QCursor& cursor) | 设置全局光标的形状. 对整个程序中的所有 widget 都会⽣效. 覆盖上⾯的 setCursor 设置的内容. |
其中细节:
- 前两个cursor和setCursor的范围是同一个界面中,设置指定的光标
- 而 QGuiApplication::setOverrideCurSor:设置全局的光标
实操:修改光标的图标 QPixmap
当拖拽一个控件后可以直接在右侧属性中进行快速的修改cursor的样式:
当然也可通过代码的形式进行修改:
- 创建cursor对象,通过构造初始化进行设置光标
- 构造函数中修改,对ui中的按钮进行调用设置cursor的函数,传递cursor对象即可
不难发现:Qt中内置的光标形式有许多(如下图),但都比较的老套了
Qt允许通过自定义的图片来设置光标:
先准备一个图片,把图片导入到项目中,在代码中访问图片,基于这个图片构造出光标对象并设置到cursor中
- 通过qrc导入图片
- QPixmap:这个对象来表示一个图片,建议直接在栈上定义,构造传入刚刚创建的图片路径
- 构造一个光标对象,并构造传递QPixmap图片对象
- 默认点击的是图片的左上角(鼠标的位置)。但可以继续在构造中传递坐标,确定鼠标点击的位置(以左上角为原点的坐标位置),也就是设置光标热点所在的位置(也就是cursor参数中Pixmap后面的两个参数)
- 在把光标设置进去,this指针调用setCursor传递刚刚创建的Cursor对象即可
如我们选择的图片可能比较的大,
- pixmap中的scaled函数进行重新设置图片大小进行缩放
- 注意缩放并不是修改图片对象,而是返回一个新的图片的对象副本
推荐一个矢量图库:阿里巴巴矢量图标库(免费下载)
源码:
#include "widget.h"
#include "ui_widget.h"#include <QCursor>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPixmap pixmap(":/loading.png");//使用QPixmap存储创建的图片pixmap = pixmap.scaled(20,20);//scaled缩放,注意是返回而不是直接覆盖QCursor cursor(pixmap,10,10);//将图片给到QCursorui->pushButton->setCursor(cursor);}Widget::~Widget()
{delete ui;
}
最终使用scaled进行缩放的效果:
9. Front
API | 说明 |
---|---|
font() | 获取当前 widget 的字体信息. 返回 QFont 对象. |
setFont(const QFont& font) | 设置当前 widget 的字体信息 |
关于QFont
也就是一些字体的属性(都很好理解也是最常用的):
属性 | 说明 |
---|---|
family | 字体家族 ⽐如 “楷体”, “宋体”, “微软雅⿊” 等 |
pointSize | 字体⼤⼩ px |
weight | 字体粗细 以数值⽅式表⽰粗细程度取值范围为 [0, 99], 数值越⼤, 越粗. |
bold | 是否加粗. 设置为 true, 相当于 weight 为 75. 设置为 false 相当于 weight 为 50 |
italic | 是否倾斜 |
underline | 是否带有下划线 |
strikeOut | 是否带有删除线 |
(上述属性具体怎么设计往往后美工/设计/UED来确定,若没有作为程序员我们就能参考下别人数如何安排的)
下面将通过代码的形式进行展示,查看具体的使用
-
通过ui拖拽一个label标签进去
-
font属性内部就能进行修改
-
其中的属性:
- 字体族:字体的类型
- 点大小:字体的大小
- 以及较好理解的概念:粗体、下划线、删除线、字距调整、反锯齿
但通过这种编辑器的修改,总归对于程序来说是不够遍历的,所以我们得通过代码的形式来写,这里就略过了较为简单(具体某个属性通过前置set进行设置即可)
10. toolTip 弹出提示(解释控件的作用)
API | 说明 |
---|---|
setToolTip | 设置 toolTip。⿏标悬停在该 widget 上时会有提⽰说明(也就是提示的内容) |
setToolTipDuring | 设置 toolTip 提⽰的时间. 单位 ms 时间到后 toolTip ⾃动消失(提示的时间) |
代码实操
- 拖拽两个按钮在界面中
- 在通过代码设置弹出提示(setToolTip)
- 设置说明:
- “这是一个yes按钮”、时间:msec毫秒 3000ms(1s = 1000ms)
- “这是一个no按钮”、1000ms
- “这是一个yes按钮”、时间:msec毫秒 3000ms(1s = 1000ms)
代码实现:
ui->pushButton_3->setToolTip("代码实现的提示");ui->pushButton_3->setToolTipDuration(5000);
附:若某种特性需要程序已启动就显示的就可以设置在构造函数中
11. focusPolicy 控件焦点
focusPolicy设置控件获取到焦点的策略
⽐如:
某个控件能否⽤⿏标选中或者能否通过 tab 键选中
再如:
界面上有一个输入框,此时必须选中这个输入框,接下来键盘才能将输入进去,这种选中的过程就是焦点
实际常见中:
如笔试过程中,遇到不会的题,能不能切到百度来搜一下?此时的处理方法就是窗口焦点,你在网页中去做题,网页是始终获取到焦点的状态,一旦你切到百度/其他程序,立即就知道失去了焦点的也就代表有作弊可能了~
所以 GUI中 窗口/控件 焦点是非常关键的~~
具体方法:
API | 说明 |
---|---|
focusPolicy() | 获取该 widget 的 focusPolicy, 返回 Qt::FocusPolicy |
setFocusPolicy(Qt::FocusPolicy policy) | 设置 widget 的 focusPolicy |
其中的参数 Qt::FocusPolicy 类型,本质是枚举类型:
- Qt::NoFocus :控件不会接收键盘焦点(此时就不能被选中的意思)
- Qt::TabFocus :控件只可以通过Tab键接收焦点
- Qt::ClickFocus :控件只可以在⿏标点击时接收焦点
- Qt::StrongFocus :==控件可以通过Tab键和⿏标点击接收焦点 (默认值) ==
- Qt::WheelFocus : 类似于 Qt::StrongFocus , 同时控件也通过⿏标滚轮获取到焦点 (新增的选项, ⼀般很少使⽤)。
代码实操:
- 拖拽几个lineEdit输入框,进行查看:默认是 点击 + Tab 键接收焦点的
- 当把一个输入框设置为NoFocus就无法被选中
- 当把一个输入框设置为TabFocus此时就无法被鼠标点击选中,但可以通过Tab切换到
- 同理设置为ClickFocus时就不能tab到了
- 挺简单的自行测试哈,不好展示~
12. styleSheet Widget样式
styleSheet 类似CSS设置网页样式一样,styleSheet是设置窗口的样式
样式:描述界面具体是什么样子的~
CSS层叠样式表,在进行网页开发的时候提供方法的功能将网页设置非常好看,而Qt 就把 CSS 参考过来了,搞了一个套 QSS(样式表)
通过代码学习:
-
创建一个label控件,在右边属性中就会有styleSheed属性
-
双击后再内部通过键值对的格式进行设置样式
-
如:font-family:‘微软雅黑’、font-size:30px
- 其中和 CSS类似,是通过键值对的格式进行添加样式
- 也就是:键 : 值
- 键值对和键值对之间通过
;
分割
修改后状态:
实例:实现夜间模式
通过代码来设置样式,实现夜间模式
- 打开ui拖拽一个Plain Text Edit上去
- 在添加两个按钮并命名为“日间模式”、“夜间模式”,设置其信号槽
- 对于light(日间模式)来说:
- 将窗口和输入框 调用 setStyleSheet 进行设置样式
- 内容:background-color:white;
- 也就是设置背景色为白色(调成了日间模式)
- 其中对于输入框来说还要添加color:black设置字体为黑色
- 设置按钮样式,将他们设置为黑色 color : black(因为要看到见)
- 对于dark夜间模式
- 如法炮制
- 设置窗口和输入框的样式:黑色背景、白色字体
- 按钮样式为 白色(为了在夜间能看到)
- 注意点:千万要注意单词的拼写!(不会出错,但样式不会生效)
- 对于
;
来说可加可不加
槽函数的实现
void Widget::on_pushButton_3_clicked()//不好的命名规范~
{//点击日间模式this->setStyleSheet("background-color: RGB(240,240,240)");ui->lineEdit->setStyleSheet("color: black");ui->pushButton_3->setStyleSheet("color: black");ui->pushButton_4->setStyleSheet("color: black");
}void Widget::on_pushButton_4_clicked()
{//点击夜间模式this->setStyleSheet("background-color: black");ui->lineEdit->setStyleSheet("color: white");ui->pushButton_3->setStyleSheet("color: white");ui->pushButton_4->setStyleSheet("color: white");
}
其中若直接变化则会出现问题:
日间模式的窗口背景颜色和默认的窗口背景颜色不一样了,主要是因为颜色的不一样,那么应该怎么解决呢?具体让我们进行往下看…
计算机中颜色是如何表示的RGB
CSS/QSS中是直接使用单词来设置颜色的,white、black、red、green
那么颜色有多少种呢?无数种~
而在计算机中,使用RGB的方式来表示颜色
RGB就是三原色(光的三原色),通过这三种颜色进行不同比例的混合就能构成不同的颜色
- R:red
- G:green
- B:blue
屏幕上的像素就是一个包含RGB的小灯泡
计算机中通常使用一个字节表示R、G、B。也就是每个颜色的值都是: 0 ~ 255
例如:
- 假设R这个分量为 255 ,这表示红色的比例拉满
- 再如:RGB(255,0,255):红色拉满,绿色没有、蓝色拉满
还能使用十六进制表示:
- #FF00FF:其实和上面是一样的 因为 FF 就对应着上面的红色(因为1个十六进制代表4个二进制,此时2个十六进制就是8个二进制,也就是8位,也就是 0 ~ 255 所以最开始的前两个十六进制就代表着红色,其余的就是 绿色和蓝色)
- 所以同样表示:红色拉满,绿色没有、蓝色拉满
那么回到前面的问题,Widget的初始化背景色是多少数值呢?
- 通过ps的取色器,但没必要使用ps
- 咋们可以直接使用qq中的截屏快速的来查看:
通过qq截屏读取RGB颜色就知道了,初始背景的RGB(240,240,240)
所以对于日间模式的窗口的颜色设置就改成 rgb(240,240,240),这样就能保证颜色一致~
Widget中还有许多属性,这里就不过诉了,可以自行调阅文档了解哈~
本章完。预知后事如何,暂听下回分解。
如果有任何问题欢迎讨论哈!
如果觉得这篇文章对你有所帮助的话点点赞吧!
持续更新大量Qt细致内容,早关注不迷路。
相关文章:
【Qt】控件的理解 和 基础控件 QWidget 属性详解(通俗易懂+附源码+思维导图框架)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 通过上一章对信号槽的理解相信你对Qt的认识肯定有了很大的进步,下面将通过本篇文章带你深入的认识Widget控件(主窗口࿰…...
oracle将表字段逗号分隔的值进行拆分,并替换值
需求背景:需要源数据变动,需要对历史表已存的字段值根据源数据进行更新。如果是单字段存值,直接根据映射表关联修改即可。但字段里面若存的值是以逗号分割,比如旧值:‘old1,old2,old3’,要根据映射关系调整…...
用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能
一、知识介绍 带头节点的链队列是一种基于链表实现的队列结构,它在链表的头部添加了一个特殊的节点,称为头节点。头节点不存储实际的数据元素,主要作用是作为链表的起点,简化队列的操作和边界条件处理。 1.节点结构 链队列的每…...
webpack基础使用了解(入口、出口、插件、加载器、优化、别名、打包模式、环境变量、代码分割等)
目录 1、webpack简介2、简单示例3、入口(entry)和输出(output)4、自动生成html文件5、打包css代码6、优化(单独提取css代码)7、优化(压缩过程)8、打包less代码9、打包图片10、搭建开发环境(webpack-dev-server…...
【项目】基于MCP+Tabelstore架构实现知识库答疑系统
基于MCPTabelstore架构实现知识库答疑系统 整体流程设计(一)Agent 架构(二)知识库存储(1)向量数据库Tablestore(2)MCP Server (三)知识库构建(1&a…...
C语言高频面试题——malloc 和 calloc区别
在 C 语言中,malloc 和 calloc 都是用于动态内存分配的函数,但它们在 内存初始化、参数形式 和 使用场景 上有显著区别。以下是详细的对比分析: 1. 函数原型 malloc void* malloc(size_t size);功能:分配 未初始化 的连续内存块…...
深入探讨JavaScript性能瓶颈与优化实战指南
JavaScript作为现代Web开发的核心语言,其性能直接影响用户体验与业务指标。随着2025年前端应用的复杂性持续增加,性能优化已成为开发者必须掌握的核心技能。本文将从性能瓶颈分析、优化策略、工具使用三个维度,结合实战案例,系统梳理JavaScript性能优化的关键路径。 一、Ja…...
[创业之路-376]:企业法务 - 创业,不同的企业形态,个人承担的风险、收益、税费、成本不同
在企业法务领域,创业时选择不同的企业形态,个人在风险承担、收益分配、税费负担及运营成本方面存在显著差异。以下从个人独资企业、合伙企业、有限责任公司、股份有限公司四种常见形态展开分析: 一、个人承担的风险 个人独资企业 风险类型&…...
【Lua】Lua 入门知识点总结
Lua 入门学习笔记 本教程旨在帮助有编程基础的学习者快速入门Lua编程语言。包括Lua中变量的声明与使用,包括全局变量和局部变量的区别,以及nil类型的概念、数值型、字符串和函数的基本操作,包括16进制表示、科学计数法、字符串连接、函数声明…...
低空经济 WebGIS 无人机配送 | 图扑数字孪生
2024 年,”低空经济” 首次写入政府工作报告,在政策驱动下各地纷纷把握政策机遇,从基建网络、场景创新、产业生态、政策激励等方面,构建 “规划-建设-应用-赋能” 的系统性布局,作为新质生产力的重要体现,推…...
【程序员 NLP 入门】词嵌入 - 如何基于计数的方法表示文本? (★小白必会版★)
🌟 嗨,你好,我是 青松 ! 🌈 希望用我的经验,让“程序猿”的AI学习之路走的更容易些,若我的经验能为你前行的道路增添一丝轻松,我将倍感荣幸!共勉~ 【程序员 NLP 入门】词…...
基于机器学习的多光谱遥感图像分类方法研究与定量评估
多光谱遥感技术通过获取可见光至红外波段的光谱信息,为地质勘探、农业监测、环境调查等领域提供了重要支持。与普通数码相机相比,多光谱成像能记录更丰富的波段数据(如近红外、短波红外等),从而更精准地识别地物特征。…...
BEVDepth: Acquisition of Reliable Depth for Multi-View 3D Object Detection
背景 基于多视角图片的3D感知被LSS证明是可行的,它使用估计的深度将图像特征转化为3D视椎,再将其压缩到BEV平面上。对于这个得到的BEV特征图,它支持端到端训练以及各种下游任务。但是对于深度估计这一块学习的深度质量如何,到目前为止没有相关工作研究。 贡献 本文的贡献…...
【Linux】静态库 动态库
🌻个人主页:路飞雪吖~ 🌠专栏:Linux 目录 一、👑静态库和动态库 静态库: 动态库: 🌠手动制作静态库 && 手动调用一下我们自己写的静态库 1> 安装到系统里面 ✨生成静…...
Java转Go日记(六):TCP黏包
服务端代码如下: // socket_stick/server/main.gofunc process(conn net.Conn) {defer conn.Close()reader : bufio.NewReader(conn)var buf [1024]bytefor {n, err : reader.Read(buf[:])if err io.EOF {break}if err ! nil {fmt.Println("read from client…...
(51单片机)LCD显示温度(DS18B20教程)(LCD1602教程)(延时函数教程)(单总线教程)
演示视频: LCD显示温度 源代码 如上图将9个文放在Keli5 中即可,然后烧录在单片机中就行了 烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频: 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.…...
【通过Docker快速部署Tomcat9.0】
文章目录 前言一、部署docker二、部署Tomcat2.1 创建存储卷2.2 运行tomcat容器2.3 查看tomcat容器2.4 查看端口是否监听2.5 防火墙开放端口 三、访问Tomcat 前言 Tomcat介绍 Tomcat 是由 Apache 软件基金会(Apache Software Foundation)开发的一个开源 …...
云原生--基础篇-3--云原生概述(云、原生、云计算、核心组成、核心特点)
1、什么是云和原生 (1)、什么是云? “云”指的是云计算环境,代表应用运行的基础设施和资源。依赖并充分利用云计算的弹性、分布式和资源池化能力。 核心含义: 1、云计算基础设施 云原生应用的设计和运行完全基于云…...
Spark-Streaming
Spark-Streaming概述 DStream实操 案例一:WordCount案例 需求:使用 netcat 工具向 9999 端口不断的发送数据,通过 SparkStreaming 读取端口数据并统计不同单词出现的次数 实验步骤: 添加依赖 <dependency> <gro…...
乐视系列玩机------乐视2 x620红灯 黑砖刷写教程以及新版刷写工具的详细释义
乐视x620在上期解析了普通黑砖情况下的救砖刷机过程。但在一些例外的情况下。使用上面的步骤会一直刷写报错 。此种情况就需要另外一种强制刷写方法来救砖 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x620系列 红灯 黑砖线刷救砖的步骤 2💝💝💝----图…...
若依SpringCloud项目-定制微服务模块
若依SpringCloud项目-定制微服务模块 关于微服务先不过多介绍,刚开始熟悉并不能讲的很彻底,成熟的微服务项目-若依SpringCloud就是一个典型的微服务架构工程(网上有很多教程了,不明白的可以学习一下)。 我正在看的视…...
【扫描件批量改名】批量识别扫描件PDF指定区域内容,用识别的内容修改PDF文件名,基于C++和腾讯OCR的实现方案,超详细
批量识别扫描件PDF指定区域内容并重命名文件方案 应用场景 本方案适用于以下场景: 企业档案数字化管理:批量处理扫描的合同、发票等文件,按内容自动分类命名财务票据处理:自动识别票据上的关键信息(如发票号码、日期)用于归档医疗记录管理:从扫描的检查报告中提取患者I…...
学习Docker遇到的问题
目录 1、拉取hello-world镜像报错 1. 检查网络连接 排查: 2. 配置 Docker 镜像加速器(推荐) 具体解决步骤: 1.在服务器上创建并修改配置文件,添加Docker镜像加速器地址: 2. 重启Docker 3. 拉取hello-world镜像 2、删除镜像出现异常 3、 容器内部不能运行ping命令 …...
Docker 数据卷
目录 一、数据卷(Data Volume) 二、使用 1、单独建立数据卷 2、挂载主机数据卷 3、数据卷容器挂载 基本语法: 工作原理: 主要用途: 使用事例: 一、数据卷(Data Volume) 数据卷的使用,类似于 Linux 下对目录或文件进行 mount 数据卷(Data Volume)是一个可供一个或多…...
【数据结构】励志大厂版·初级(二刷复习)双链表
前引:今天学习的双链表属于链表结构中最复杂的一种(带头双向循环链表),按照安排,我们会先进行复习,如何实现双链表,如基本的头插、头删、尾删、尾插,掌握每个细节,随后进…...
通过dogssl申请ssl免费证书
SSL证书作为实现HTTPS加密的核心工具,能够确保用户与网站之间的数据传输安全。尤其是在小程序之类的开发时,要求必须通过https发起请求的情况下。学会如何免费申请一个ssl证书就很有必要了。这里我分享一下,我通过dogssl如何申请ssl的。 一&…...
路由与路由器
路由的概念 路由是指在网络通讯中,从源设备到目标设备路径的选择过程。路由器是实现这一过程的关键设备,它通过转发数据包来实现网络的互联。路由工作在OSI参考模型的第三层,‘网络层’。 路由器的基本原理 路由器通过维护一张路由表来决定…...
Docker底层原理浅析 | namespace+cgroups+文件系统
本文目录 1. Linux NamespaceLinux系统里是否只能有一个pid为1的进程?namespace机制查看namespacenamespace机制测试使用Docker验证namespace机制 2. Dcoerk网络模式3.Control groups4.文件系统(联合文件系统)5. 容器格式 1. Linux Namespace…...
【无人机】使用扩展卡尔曼滤波 (EKF) 算法来处理传感器测量,各传感器的参数设置,高度数据融合、不同传感器融合模式
目录 #1、IMU #2、磁力计 #3、高度 #典型配置 #4、气压计 #静压位置误差修正 #气压计偏置补偿 #5、全球导航系统/全球定位系统--GNSS/GPS #位置和速度测量 #偏航测量 #GPS 速度的偏航 #双接收器 #GNSS 性能要求 #6、测距 #条件范围辅助-Conditional range aidin…...
常见的raid有哪些,使用场景是什么?
RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理硬盘组合成一个逻辑硬盘的技术,目的是通过数据冗余和/或并行访问提高性能、容错能力和存储容量。不同的 RAID 级别有不同的实现方式和应用场景。以下…...
《 C++ 点滴漫谈: 三十四 》从重复到泛型,C++ 函数模板的诞生之路
一、引言 在 C 编程的世界里,类型是一切的基础。我们为 int 写一个求最大值的函数,为 double 写一个相似的函数,为 std::string 又写一个……看似合理的行为,逐渐堆积成了难以维护的 “函数墙”。这些函数逻辑几乎一致࿰…...
EasyRTC打造无人机低延迟高清实时通信监控全场景解决方案
一、方案背景 随着无人机技术的飞速发展,其在航拍、物流配送、农业监测、应急救援等多个领域的应用日益广泛。然而,无人机在实际作业过程中面临着诸多挑战,如通信延迟、数据传输不稳定、监控范围有限等。EasyRTC作为一种高效、低延迟的实时通…...
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出)
【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出) 引言 本文使用状态空间模型实现失业率递归预测,状态空间模型(State Space Model, SSM)是一种用于描述动态系统行为的…...
关于大数据的基础知识(三)——数据安全与合规
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(三&a…...
从信息泄露到内网控制
0x01 背景 之前常见用rce、文件上传等漏洞获取webshell,偶然遇到一次敏感信息泄露获取权限的渗透,简单记录一下过程。 0x02 信息泄露 发现系统某端口部署了minio服务,经过探测发现存在minio存储桶遍历 使用利用工具把泄露的文件全部整理一…...
【Qt】QDialog类
🌈 个人主页:Zfox_ 🔥 系列专栏:Qt 目录 一:🔥 对话框 - QDialog 🦋 基本介绍🦋 对话框分类🦋 Qt 内置对话框🎀 QMessageBox -消息对话框🎀 QColo…...
【Spring Boot基础】MyBatis的基础操作:增删查改、列名和属性名匹配 -- XML实现
MyBatis的基础操作 1. MyBatis XML配置文件1.1 简单介绍1.2 配置连接字符串和MyBatis1.3 XMl文件实现--分层1.4 XMl文件实现--举例 2.增删改查操作2.1 增(insert)2.1.1 不使用Param2.1.2 用Param2.1.3 返回自增键 2.2 删(delete)2…...
谷歌推出探索型推荐新范式:双LLM架构重塑用户兴趣挖掘
文章目录 1. 背景1.1 闭环困境1.2 谷歌的两次失败尝试1.2.1 尝试一:轻量微调1.2.2 尝试二:RLHF 强化学习微调 1.3 双LLM范式的提出1.3.1 模型1:Novelty LLM — 负责生成“探索方向”1.3.2 模型2:Alignment LLM — 负责评估“相关性…...
Linux kernel signal原理(下)- aarch64架构sigreturn流程
一、前言 在上篇中写到了linux中signal的处理流程,在do_signal信号处理的流程最后,会通过sigreturn再次回到线程现场,上篇文章中介绍了在X86_64架构下的实现,本篇中介绍下在aarch64架构下的实现原理。 二、sigaction系统调用 #i…...
使用 LangChain + Higress + Elasticsearch 构建 RAG 应用
RAG(Retrieval Augmented Generation,检索增强生成) 是一种结合了信息检索与生成式大语言模型(LLM)的技术。它的核心思想是:在生成模型输出内容之前,先从外部知识库或数据源中检索相关信息&…...
【Linux】46.网络基础(3.3)
文章目录 5. 其他重要协议或技术5.1 DNS(Domain Name System)5.1.1 DNS背景5.1.2 域名简介 5.2 ICMP协议5.2.1 ICMP功能5.2.2 ICMP的报文格式5.2.3 ping命令5.2.4 一个值得注意的坑5.2.5 traceroute命令 5.3 NAT技术5.3.1 NAT技术背景5.3.2 NAT IP转换过程5.3.3 NAPT5.3.4 NAT技…...
【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南
图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准,越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现:打包成的EXE程序无法正常启动SteamVR,或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …...
【sylar-webserver】重构 增加内存池
文章目录 内存池设定结构ThreadCacheCentralCachePageCache allocatedeallocate测试 参考 https://github.com/youngyangyang04/memory-pool 我的代码实现见 https://github.com/star-cs/webserver 内存池 ThreadCache(线程本地缓存) 每个线程独立的内存…...
云账号安全事件分析:黑客利用RAM子账户发起ECS命令执行攻击
事件背景 某企业云监控系统触发高危告警,提示API请求中包含黑客工具特征(cf_framework),攻击者试图通过泄露的RAM子账户凭据调用ECS高危API。以下是攻击关键信息整理: 字段详情告警原因API请求包含黑客工具特征(cf_framework)攻击实体RAM子账户 mq泄露凭证AccessKey ID…...
Node.js 模块导入的基本流程
Node.js 模块导入的基本流程,主要是 CommonJS 模块加载机制(即使用 require())的内部执行步骤。下面我用清晰的结构给你梳理一下这个过程: ✅ Node.js 模块导入的基本流程(使用 require()) const someModu…...
Unitest和pytest使用方法
unittest 是 Python 自带的单元测试框架,用于编写和运行可重复的测试用例。它的核心思想是通过断言(assertions)验证代码的行为是否符合预期。以下是 unittest 的基本使用方法: 1. 基本结构 1.1 创建测试类 继承 unittest.TestC…...
wps批量修改字体
选择这个小箭头 找到需要修改的字体如正文,右击修改选择合适的字体确定即可...
【Linux网络】各版本TCP服务器构建 - 从理解到实现
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
航电系统多模态融合技术要点
一、技术要点 1. 多模态数据特性分析 异构数据对齐:需处理不同传感器(如雷达、摄像头、IMU、ADS-B等)在时间、空间、精度和采样率上的差异,需设计同步机制(如硬件时钟同步、软件插值对齐)。 数据预处…...
【Git】branch合并分支
在 Git 中,将分支合并到 main 分支是一个常见的操作。以下是详细的步骤和说明,帮助你完成这个过程。 1. 确保你在正确的分支上 首先,你需要确保当前所在的分支是 main 分支(或者你要合并到的目标分支)。 检查当前分支…...