qt-C++笔记之动画框架(Qt Animation Framework)入门
qt-C++笔记之动画框架(Qt Animation Framework)入门
code review!

在 Linux 平台上,使用 C++ 和 Qt 框架实现动画是一个非常好的选择。Qt 提供了强大的动画框架(Qt Animation Framework),使得动画的实现变得简单高效。下面将介绍 Qt 动画的基本概念与入门使用,并进一步探讨 QTimeLine、QEasingCurve 的用法,以及 Qt 动画框架中几个重要的类之间的区别。
文章目录
- qt-C++笔记之动画框架(Qt Animation Framework)入门
- 1. Qt 动画框架简介
- 1.1 核心类
- 1.1.1 QPropertyAnimation
- 1.1.2 QSequentialAnimationGroup
- 1.1.3 QParallelAnimationGroup
- 1.1.4 QGraphicsItemAnimation
- 1.1.5 QAnimationDriver
- 1.2 动画作用域
- 1.2.1 UI 部件动画
- 1.2.2 场景动画
- 1.2.3 自定义动画
- 2. 简单动画示例
- 2.1 示例 1:移动一个按钮
- 2.1.1 代码说明
- 3. 组合动画
- 3.1 示例 2:顺序执行多个动画
- 3.2 示例 3:并行执行多个动画
- 4. 自定义动画曲线
- 4.1 常用曲线类型
- 4.2 自定义动画曲线示例
- 5. 在 QGraphicsView 中实现动画
- 6. 总结
- 7. QTimeLine 是什么
- 7.1 核心功能
- 7.2 关键属性和方法
- 7.3 常见动画曲线(CurveShape)
- 7.4 QTimeLine 的信号
- 7.5 简单用法示例
- 7.6 进阶用法:配合 QGraphicsItemAnimation
- 7.7 优缺点与结论
- 8. QTimeLine 和 QEasingCurve 的区别
- 8.1 一、核心区别
- 8.2 二、QTimeLine 详解
- 8.3 三、QEasingCurve 详解
- 8.4 四、两者关系与配合
- 8.5 五、总结对比
- 9. QAbstractAnimation、QVariantAnimation 和 QPropertyAnimation 的区别
- 9.1 一、继承关系
- 9.2 二、核心区别
- 9.3 三、详细分析
- 9.3.1.`QAbstractAnimation` 示例:自定义动画基类
- 9.3.2.`QVariantAnimation` 示例:插值动画
- 9.3.3.`QPropertyAnimation` 示例:操作对象的属性动画
- 9.3.4.区别总结
- 9.4 四、对比总结
1. Qt 动画框架简介
1.1 核心类
1.1.1 QPropertyAnimation
- 用于对对象属性(如位置、大小、透明度等)进行动画处理,直接操作
QObject的特定属性。
1.1.2 QSequentialAnimationGroup
- 用于按顺序播放多个动画。
1.1.3 QParallelAnimationGroup
- 用于并行播放多个动画。
1.1.4 QGraphicsItemAnimation
- 用于对
QGraphicsItem(图形场景中的对象)进行动画处理。 - 通常与
QTimeLine搭配使用。
1.1.5 QAnimationDriver
- 自定义动画的驱动类,用于更底层地控制动画刷新。
1.2 动画作用域
1.2.1 UI 部件动画
- 对 GUI 组件(如按钮、窗口等)进行动画处理(位置、大小、透明度等)。
1.2.2 场景动画
- 对
QGraphicsView场景中的对象进行动画处理,适合做复杂的 2D 场景交互或游戏等。
1.2.3 自定义动画
- 如果需要更复杂的动画效果,可以自定义动画逻辑或插值方式。
2. 简单动画示例
2.1 示例 1:移动一个按钮
下面的示例展示了如何使用 QPropertyAnimation 将一个按钮从左上角平滑移动到右下角,并添加弹跳效果:
#include <QApplication>
#include <QPushButton>
#include <QPropertyAnimation>
#include <QEasingCurve>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建一个按钮QPushButton button("Move Me");button.resize(100, 50);button.show();// 创建一个属性动画QPropertyAnimation *animation = new QPropertyAnimation(&button, "geometry");// 设置动画时长 2 秒animation->setDuration(2000);// 动画的起始位置animation->setStartValue(QRect(0, 0, 100, 50));// 动画的结束位置animation->setEndValue(QRect(300, 300, 100, 50));// 设置动画曲线(弹跳效果)animation->setEasingCurve(QEasingCurve::OutBounce);// 开始动画animation->start();return app.exec();
}
运行

2.1.1 代码说明
-
QPropertyAnimation animation(&button, "geometry")- 指定了对按钮的
geometry属性进行动画,geometry决定了部件的在屏幕上的位置和大小。
- 指定了对按钮的
-
setStartValue与setEndValue- 分别设定了动画的初始位置和结束位置。
-
setEasingCurve(QEasingCurve::OutBounce)- 设置了弹跳缓动曲线,动画结束时会呈现弹跳的效果。
3. 组合动画
有时我们需要在一个动画之后紧接着播放另一个动画,或者同时播放多个动画,这可以使用 QSequentialAnimationGroup 和 QParallelAnimationGroup 来实现。
3.1 示例 2:顺序执行多个动画
#include <QApplication>
#include <QPushButton>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>int main(int argc, char *argv[]) {QApplication app(argc, argv);QPushButton button("Animate Me");button.resize(100, 50);button.show();// 创建两个属性动画QPropertyAnimation *animation1 = new QPropertyAnimation(&button, "geometry");animation1->setDuration(1000);animation1->setStartValue(QRect(0, 0, 100, 50));animation1->setEndValue(QRect(300, 0, 100, 50));QPropertyAnimation *animation2 = new QPropertyAnimation(&button, "geometry");animation2->setDuration(1000);animation2->setStartValue(QRect(300, 0, 100, 50));animation2->setEndValue(QRect(300, 300, 100, 50));// 创建一个顺序动画组QSequentialAnimationGroup group;group.addAnimation(animation1);group.addAnimation(animation2);// 开始动画group.start();return app.exec();
}
运行

3.2 示例 3:并行执行多个动画
#include <QApplication>
#include <QPushButton>
#include <QLabel>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>int main(int argc, char *argv[]) {QApplication app(argc, argv);QPushButton button("Button");QLabel label("Label");button.resize(100, 50);label.resize(100, 50);button.show();label.show();// 创建属性动画QPropertyAnimation *buttonAnimation = new QPropertyAnimation(&button, "geometry");buttonAnimation->setDuration(2000);buttonAnimation->setStartValue(QRect(0, 0, 100, 50));buttonAnimation->setEndValue(QRect(300, 300, 100, 50));QPropertyAnimation *labelAnimation = new QPropertyAnimation(&label, "geometry");labelAnimation->setDuration(2000);labelAnimation->setStartValue(QRect(0, 300, 100, 50));labelAnimation->setEndValue(QRect(300, 0, 100, 50));// 创建一个并行动画组QParallelAnimationGroup group;group.addAnimation(buttonAnimation);group.addAnimation(labelAnimation);// 开始动画group.start();return app.exec();
}
运行

4. 自定义动画曲线
Qt 提供了多种内置的动画曲线,比如线性、弹跳、缓动等。如果默认曲线无法满足需求,还可以使用 QEasingCurve 自定义动画曲线。
4.1 常用曲线类型
QEasingCurve::Linear:线性插值QEasingCurve::InQuad:缓入二次方QEasingCurve::OutBounce:弹跳效果
4.2 自定义动画曲线示例
QEasingCurve customCurve([](qreal t) -> qreal {// 这里使用简单的二次函数曲线 y = t^2return t * t;
});
animation->setEasingCurve(customCurve);
5. 在 QGraphicsView 中实现动画
如果使用 QGraphicsView 和 QGraphicsItem,可以通过 QGraphicsItemAnimation + QTimeLine 进行更灵活的动画控制。以下示例演示了如何为图形项做一个旋转动画:
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QTimeLine>
#include <QGraphicsItemAnimation>int main(int argc, char *argv[]) {QApplication app(argc, argv);QGraphicsView view;QGraphicsScene scene;view.setScene(&scene);QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);QTimeLine *timer = new QTimeLine(2000);timer->setFrameRange(0, 100);QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;animation->setItem(rect);animation->setTimeLine(timer);for (int i = 0; i <= 100; ++i) {// 让矩形在 2 秒内旋转 360 度animation->setRotationAt(i / 100.0, i * 3.6);}timer->start();view.show();return app.exec();
}
实际运行程序
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QTimeLine>
#include <QGraphicsItemAnimation>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建视图和场景QGraphicsView view;view.move(100, 100); // 屏幕左上角 (100, 100)QGraphicsScene scene;view.setScene(&scene);view.setFixedSize(300, 300); // 窗口大小view.setWindowTitle("Animation Demo"); // 窗口标题// 设置场景范围scene.setSceneRect(0, 0, 300, 300);// 添加矩形QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);rect->setPos(100, 100); // 矩形的初始位置// 创建时间线和动画QTimeLine *timer = new QTimeLine(2000);timer->setFrameRange(0, 100);QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;animation->setItem(rect);animation->setTimeLine(timer);for (int i = 0; i <= 100; ++i) {// 让矩形在 2 秒内旋转 360 度animation->setRotationAt(i / 100.0, i * 3.6);}// 启动动画并显示视图timer->start();view.show();return app.exec();
}
运行

6. 总结
Qt 提供了非常强大的动画框架,适用于各种场景,包括简单的 UI 动画、复杂的场景动画,以及自定义动画效果。建议先从 QPropertyAnimation 入门,熟悉后再学习 QSequentialAnimationGroup 与 QParallelAnimationGroup 的组合用法,以及在 QGraphicsView 场景中使用 QGraphicsItemAnimation。如果需要更现代化、更丰富的动画效果,还可以进一步探索 QML 动画与 C++ 的结合。
7. QTimeLine 是什么
QTimeLine 是 Qt 提供的一个时间驱动类,主要用于控制动画的时间轴。它可以生成一个时间流,用来精确地管理动画的时长、帧数、循环次数以及动画曲线等。
7.1 核心功能
- 控制动画的时间流(定时触发事件或更新插值)
- 配合
QGraphicsItemAnimation使用 - 自定义动画的加速、减速或循环模式
7.2 关键属性和方法
| 属性/方法 | 描述 |
|---|---|
| setDuration(int ms) | 设置动画总时长(毫秒)。 |
| setFrameRange(int start, int end) | 设置帧范围。 |
| setCurveShape(QTimeLine::CurveShape) | 设置动画曲线(如线性、缓入、缓出等)。 |
| start() | 开始动画。 |
| stop() | 停止动画。 |
| valueForTime(int ms) | 根据当前时间计算动画进度值(通常在 [0.0, 1.0])。 |
| setUpdateInterval(int ms) | 设置更新间隔(毫秒)。 |
| setLoopCount(int loops) | 设置动画循环次数(0 表示无限循环)。 |
| state() | 获取当前动画状态(Running、Paused、Stopped 等)。 |
7.3 常见动画曲线(CurveShape)
| 曲线类型 | 描述 |
|---|---|
| LinearCurve | 线性变化,恒定速度 |
| EaseInCurve | 缓入曲线,开始时慢,后期加速 |
| EaseOutCurve | 缓出曲线,开始时快,后期减速 |
| EaseInOutCurve | 缓入缓出曲线,开始结束时都较慢 |
| SineCurve | 正弦曲线,平滑的缓入缓出变化 |
| CosineCurve | 余弦曲线,与正弦曲线类似 |
7.4 QTimeLine 的信号
| 信号 | 描述 |
|---|---|
| frameChanged(int frame) | 当前帧改变时触发 |
| valueChanged(qreal value) | 当前进度值改变时触发(范围 [0.0, 1.0]) |
| stateChanged(State newState) | 动画状态改变时触发 |
| finished() | 动画结束时触发 |
7.5 简单用法示例
以下例子演示用 QTimeLine 在 2 秒内把按钮从 x=0 移到 x=300:
#include <QApplication>
#include <QPushButton>
#include <QTimeLine>int main(int argc, char *argv[]) {QApplication app(argc, argv);QPushButton button("Move Me");button.resize(100, 50);button.show();QTimeLine timeline(2000); // 动画时长 2 秒timeline.setFrameRange(0, 300); // 帧范围timeline.setCurveShape(QTimeLine::EaseInOutCurve);QObject::connect(&timeline, &QTimeLine::frameChanged, [&button](int frame) {button.move(frame, 100);});timeline.start();return app.exec();
}
运行

7.6 进阶用法:配合 QGraphicsItemAnimation
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QTimeLine>
#include <QGraphicsItemAnimation>int main(int argc, char *argv[]) {QApplication app(argc, argv);QGraphicsScene scene;QGraphicsView view(&scene);QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);QTimeLine *timeline = new QTimeLine(2000);timeline->setFrameRange(0, 100);QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;animation->setItem(rect);animation->setTimeLine(timeline);for (int i = 0; i <= 100; ++i) {animation->setRotationAt(i / 100.0, i * 3.6);}view.show();timeline->start();return app.exec();
}
7.7 优缺点与结论
-
优点
- 提供完整的时间管理(时长、帧数、循环等)
- 可与
QGraphicsItemAnimation配合,实现更精细的动画控制
-
缺点
- 对于现代的 Qt 属性动画或 QML 动画而言,
QTimeLine可能显得繁琐 - 需要手动管理插值或场景更新
- 对于现代的 Qt 属性动画或 QML 动画而言,
-
结论
QTimeLine在需要精准控制帧数或需要自定义时间逻辑的场景下依旧实用
8. QTimeLine 和 QEasingCurve 的区别
这两个类在 Qt 动画框架中分别承担不同的职责,可以相互配合使用,但并不互斥。
8.1 一、核心区别
| 特性 | QTimeLine | QEasingCurve |
|---|---|---|
| 定义 | 时间轴类,用于生成动画的时间流 | 数学曲线类,用于定义动画的缓动插值 |
| 作用 | 控制动画的进度(时长、帧数、循环) | 改变动画速度/插值模式(线性、弹跳、缓动等) |
| 输出 | 当前时间或帧信息 | 根据输入进度返回相应缓动后的数值 |
| 使用场景 | 精准时间/帧控制 | 定义动画的加速、减速、弹跳等视觉效果 |
8.2 二、QTimeLine 详解
- 提供动画的整体时间控制
- 可以设置时长、帧范围、循环次数、曲线形状
- 常用于
QGraphicsItemAnimation等需要时间驱动的场合
8.3 三、QEasingCurve 详解
- 定义动画的插值方式(线性、缓入缓出、弹跳等)
- 不独立控制时间,而是根据 [0.0, 1.0] 的输入值,返回不同的插值结果
- 通常与
QPropertyAnimation或QTimeLine配合使用
8.4 四、两者关系与配合
QTimeLine生成一个随时间变化的进度值t,范围在 [0.0, 1.0]QEasingCurve根据进度值t计算出缓动后的插值值- 典型用法:
easedValue = curve.valueForProgress(t)
8.5 五、总结对比
- QTimeLine:管理时间进度与帧信息,提供事件驱动
- QEasingCurve:管理插值模式,使动画效果更平滑或更富表现力
它们可以结合使用,也可分别使用在不同的动画需求场景下。
9. QAbstractAnimation、QVariantAnimation 和 QPropertyAnimation 的区别
在 Qt 动画框架中,这三个类具有从抽象到具体的继承关系,主要差异在于能否直接使用以及应用场景是否针对特定属性。
9.1 一、继承关系
QAbstractAnimation└── QVariantAnimation└── QPropertyAnimation
9.2 二、核心区别
| 特性 | QAbstractAnimation | QVariantAnimation | QPropertyAnimation |
|---|---|---|---|
| 定义 | 动画框架的抽象基类 | 生成数值插值的动画类,继承自 QAbstractAnimation | 继承自 QVariantAnimation,用于动画化 QObject 的属性 |
| 作用 | 定义动画的基本接口和生命周期 | 在动画过程中生成从起始到结束的插值数值 | 直接将插值结果应用到属性(如 geometry、pos 等) |
| 是否可直接使用 | 否,需要子类实现 | 是,可直接插值 | 是,可直接操作属性 |
| 使用场景 | 自定义动画逻辑(需要自己实现插值或刷新) | 需要插值数值并在动画中使用 | 需要直接为对象属性创建动画(UI 控件、图形项等) |
9.3 三、详细分析
9.3.1.QAbstractAnimation 示例:自定义动画基类
QAbstractAnimation 是一个抽象基类,提供了基本的动画框架。通过继承它,我们可以实现自定义的动画。以下是一个简单的示例程序,创建了一个自定义动画类,使一个数字从 0 变化到 100,并在每次更新时打印值。
#include <QCoreApplication>
#include <QAbstractAnimation>
#include <QTimer>
#include <QDebug>class CustomAnimation : public QAbstractAnimation {Q_OBJECTpublic:CustomAnimation(QObject *parent = nullptr) : QAbstractAnimation(parent), m_value(0) {}int duration() const override {return 5000; // 动画持续时间为 5 秒}protected:// 更新动画进度void updateCurrentTime(int currentTime) override {m_value = (100 * currentTime) / duration(); // 根据当前时间计算值qDebug() << "Current value:" << m_value;}private:int m_value; // 当前值
};int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);CustomAnimation animation;animation.start();QTimer::singleShot(6000, &app, &QCoreApplication::quit); // 6秒后退出程序return app.exec();
}#include "main.moc"
运行

特点:
- 用途:
QAbstractAnimation是所有动画类的基类,可以通过继承它来实现完全自定义的动画逻辑。 - 灵活性:需要手动实现
updateCurrentTime()和指定动画持续时间。 - 适用场景:当现有的
QVariantAnimation或QPropertyAnimation无法满足需求时使用。
9.3.2.QVariantAnimation 示例:插值动画
QVariantAnimation 可以在两种值之间进行插值计算(支持整数、浮点数、颜色等),并在每次值更新时发出信号。以下是一个示例程序,通过插值计算让颜色从红色渐变到蓝色。
#include <QApplication>
#include <QVariantAnimation>
#include <QDebug>int main(int argc, char *argv[]) {QApplication app(argc, argv);QVariantAnimation animation;animation.setDuration(3000); // 动画持续时间为 3 秒animation.setStartValue(QColor(Qt::red)); // 起始值:红色animation.setEndValue(QColor(Qt::blue)); // 结束值:蓝色QObject::connect(&animation, &QVariantAnimation::valueChanged, [](const QVariant &value) {QColor color = value.value<QColor>();qDebug() << "Current color:" << color;});animation.start();QTimer::singleShot(4000, &app, &QCoreApplication::quit); // 4秒后退出程序return app.exec();
}
运行

特点:
- 用途:
QVariantAnimation是一个通用的插值动画类,支持多种类型(如整数、浮点数、颜色等)的值变化。 - 插值计算:根据动画进度自动计算中间值,并通过
valueChanged()信号发出。 - 适用场景:需要在两个值之间平滑过渡时使用,例如颜色渐变、大小调整等。
9.3.3.QPropertyAnimation 示例:操作对象的属性动画
QPropertyAnimation 是一个常用的动画类,用于对 QObject 的属性(如位置、大小、颜色等)进行动画处理。以下是一个示例程序,通过动画让一个矩形从左移到右。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QPropertyAnimation>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建场景和矩形QGraphicsScene scene;QGraphicsRectItem *rect = scene.addRect(0, 0, 50, 50, Qt::NoPen, Qt::blue);rect->setPos(0, 0);QGraphicsView view(&scene);view.setFixedSize(400, 200);view.show();// 创建属性动画QPropertyAnimation animation(rect, "pos"); // 动画作用于矩形的 "pos" 属性animation.setDuration(2000); // 动画持续时间为 2 秒animation.setStartValue(QPointF(0, 0)); // 起始位置animation.setEndValue(QPointF(300, 0)); // 结束位置animation.setEasingCurve(QEasingCurve::InOutQuad); // 平滑效果animation.start();return app.exec();
}
运行

特点:
- 用途:
QPropertyAnimation是专门设计用于操作 QObject 的属性的动画类。 - 自动绑定属性:通过指定属性名称(如
"pos"、"size"等),直接修改对象的属性值。 - 适用场景:对象的移动、缩放、透明度变化等动画效果。
9.3.4.区别总结
| 动画类 | 主要特点 | 适用场景 |
|---|---|---|
QAbstractAnimation | 抽象基类,允许完全自定义动画逻辑 | 特殊需求,现有动画类无法满足时使用 |
QVariantAnimation | 通用插值动画类,支持多种类型(如整数、浮点数、颜色等)的值变化,提供 valueChanged 信号 | 数值渐变(如颜色渐变、大小调整等) |
QPropertyAnimation | 操作 QObject 的属性动画,直接绑定属性名称(如 "pos"、"size"),支持平滑插值和缓动曲线 | 对象的移动、缩放、透明度变化等动画效果 |
9.4 四、对比总结
- QAbstractAnimation:框架层面的基类,提供动画生命周期管理
- QVariantAnimation:可插值任何数值,适合自定义数值动画
- QPropertyAnimation:最常用,直接作用于对象属性,易于上手
根据需求选择合适的类:若只是要动画化控件的属性,用 QPropertyAnimation;若需要自定义插值逻辑,可用 QVariantAnimation;若需要从更底层控制动画流程,可以继承 QAbstractAnimation。
通过上述内容,应该对 Qt 动画的整体框架和常用类有了比较系统的认识。可以先从最简单的 QPropertyAnimation 入手,为按钮或窗口做移动、大小、透明度的动画,再逐步尝试组合动画(顺序或并行),最后再根据需要,学习并使用 QTimeLine、QEasingCurve 等更高级或更灵活的功能。
相关文章:
qt-C++笔记之动画框架(Qt Animation Framework)入门
qt-C笔记之动画框架(Qt Animation Framework)入门 code review! 在 Linux 平台上,使用 C 和 Qt 框架实现动画是一个非常好的选择。Qt 提供了强大的动画框架(Qt Animation Framework),使得动画的实现变得简单高效。下面将介绍 Qt …...
C++26 函数契约(Contract)概览
文章目录 1. 什么是契约编程?契约编程的三大核心: 2. C26 契约编程的语法语法示例 3. 契约检查模式3.1. default 模式3.2. audit 模式3.3. axiom 模式检查模式的设置 4. 契约编程与传统 assert 的区别示例对比 5. 契约编程的应用场景6. 注意事项7. 示例: 带契约的矩形面积计算…...
Flink CDC 自定义函数处理 SQLServer XML类型数据 映射 doris json字段方案
Flink CDC 自定义函数处理 SQLServer XML类型数据方案 1. 背景 因业务使用SQLServer数据库,CDC同步到doris 数仓。对于SQLServer xml类型,doris没有相应的字段对应, 可以使用json来存储xml数据。需要进行一步转换。从 flink 自定义函数入手…...
F.interpolate函数
F.interpolate 是 PyTorch 中用于对张量(通常是图像数据)进行插值操作的函数,常用于调整张量的大小,例如改变图像的分辨率。它支持多种插值方法,包括最近邻插值、双线性插值和三次插值等。 语法 torch.nn.functional…...
华为交换机---自动备份配置到指定ftp/sftp服务器
华为交换机—自动备份配置到指定ftp服务器 需求 交换机配置修改后及时备份相关配置,每次配置变化后需要在1分钟后自动进行保存,并且将配置上传至FTP服务器;每隔30分钟,交换机自动把配置上传到FTP服务器。 1、定时保存新配置的时间间隔为*分钟(1天=1440),默认为30分钟(…...
nginx学习之路-nginx配置https服务器
文章目录 1. 生成证书2. 配置证书1. 拷贝证书文件2. 修改conf/nginx.conf文件内容 3. 查看效果1. 重载配置2. 访问 1. 生成证书 在linux系统下执行,使用openssl命令。(windows环境也可以使用cmder) # 1. 生成私钥 server2025.key(无密码保护…...
UCAS 24秋网络认证技术 CH10 SSL 复习
TLS字段、参数含义要了解每个消息是什么意思 基本方式只验证服务端,服务端有证书,变形方式加上验证客户端TLS1.3区别 协商过程 背景 Record层使用的各种加密算法参数,均由Handshake协议协商获得。 具体过程 随机数交换 Client/Server相互…...
【linux内核分析-存储】EXT4源码分析之“文件删除”原理【七万字超长合并版】(源码+关键细节分析)
EXT4源码分析之“文件删除”原理【七万字超长合并版】(源码关键细节分析),详细的跟踪了ext4文件删除的核心调用链,分析关键函数的细节,解答了开篇中提出的三个核心疑问。 文章目录 提示前言全文重点索引1.源码解析1.1 …...
代码随想录 day62 第十一章 图论part11
第十一章:图论part11 Floyd 算法精讲 Floyd 算法代码很简单,但真正理解起原理 还是需要花点功夫,大家在看代码的时候,会发现 Floyd 的代码很简单,甚至看一眼就背下来了,但我为了讲清楚原理,本…...
springboot571基于协同过滤算法的私人诊所管理系统(论文+源码)_kaic
摘 要 随着时代的发展,人们的生活方式得到巨大的改变,从而慢慢地出现了大量私人诊所信息,私人诊所信息管理需要一个现代化的管理系统,进行私人诊所的管理。 私人诊所管理系统的开发就是为了解决私人诊所信息管理的问题࿰…...
Uniapp Android 本地离线打包(详细流程)
一、简介 App 离线 SDK 暂时不支持 Kotlin,未来不清楚。 uniapp 提供了 云打包 与 本地打包 两种方案,云打包 需要排队且还有次数限制,本地打包 则就没有这些限制,而且会 本地打包 对开发 原生插件 有很大的帮助。 细节&#x…...
vite+vue3动态引入资源文件(问题已解决但离了个大谱)
教程很详细,直接上代码 解决方法(赶时间的小友理解下这函数就能解决问题了,就是处理了下路径,运气不好遇到问题再回来也不迟🤣🤣🤣) const getSvgUrl (name) > {// name: svg_1…...
通过 4 种方式快速将音乐从 iPod 传输到 Android
概括 在 iPod 上听音乐很酷,但是当您拥有最新的 Android 手机时,也许您想在新手机上欣赏 iPod 音乐。那么,你的计划是什么?如何将音乐从 iPod 传输到 Android? 如果您担心这个问题,请看看下面的方法。他们…...
ArcGIS中怎么把数据提取到指定范围(裁剪、掩膜提取)
最近,经常能收到怎么把数据提取到指定范围、栅格数据怎么裁剪、矢量数据怎么裁剪、栅格数据怎么掩膜提取的咨询。 下面是我对这个问题的解决思路: 对于矢量数据: ①首先把数据加载进来 ②软件界面上面的工具栏找到→地理处理→裁剪&#x…...
【Vaadin flow 实战】第3讲-快速上手构建VaadinFlow+Springboot的全栈web项目
快速构建VaadinFlowSpringboot的全栈web项目 温馨提示,本文讲解比较精炼,主要以快速上手开发为主。 官方提供了与本文类似的教程讲解,地址https://vaadin.com/docs/latest/getting-started 1访问vaadin官方提供的start网站(类似于 spring i…...
HBase Cassandra的部署和操作
目录 一.数据库的部署与配置 二.使用命令访问数据库 三.数据库的设计 四.编程实现数据库的访问 一.数据库的部署与配置 1.在单个节点上对进行数据库的单机部署 (1)下载apache-cassandra-4.1.7-…...
用户界面软件01
Jens Coldewey 著,Tom.X 译 本文中的模式语言逐步深入地探讨用户界面架构的设计,它基于人机工程学,足以形成一套完整的体系。如果你对这方面有兴趣,请参考[Tog92],[Coo95]和[Col95]。 本文不讨论用户界面的布局&…...
【云原生】Docker Compose 从入门到实战使用详解
目录 一、前言 二、Docker Compose 介绍 2.1 Docker Compose概述 2.2 Docker Compose特点 2.3 Docker Compose使用场景 三、Docker Compose 安装 3.1 安装docker环境 3.2 Docker Compose安装方式一 3.2.1 下载最新版 3.2.2 设置权限 3.2.3 设置软链接 3.2.4 查看版本…...
【ShuQiHere】使用 SCP 进行安全文件传输
【ShuQiHere】🚀 在日常的开发和运维工作中,文件传输是一个常见的任务。scp(Secure Copy)是一个基于 SSH 协议的文件传输工具,能够在本地和远程主机之间安全地复制文件和目录。本文将详细介绍 scp 的使用方法…...
海康威视H5player问题汇总大全
由于除了要支持Windows平台,还要支持国产系统的平台,这时就用到了H5player,但是这个在使用调试的时候会遇到各种各样的问题,便在此分享一下,供大家分享!!! 问题一:Unexp…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
