Qt 系统相关 - 事件
目录
1. 事件介绍
2. 事件的处理
示例1:处理鼠标进入和离开
示例2:当鼠标点击时,获取对应的坐标值;
3. 按键事件
3.1 单个按键
3.2 组合按键
4. 鼠标事件
4.1 鼠标单击事件
4.2 鼠标释放事件
4.3 鼠标双击事件
4.4 鼠标移动事件
4.5 滚轮事件
5. 定时器
5.1 QTimerEvent 类
5.2 QTimer 类
5.3 获取系统日期及时间
6. 事件分发器
6.1 概述
6.2 事件分发器工作原理
编辑7. 事件过滤器
1. 事件介绍
前面我们学习了信号槽,它是用户进行的各种操作,可能会产生出信号,程序员给某个信号指定槽函数,当信号触发时,就能够自动的执行到对应的槽函数。事件和信号槽非常类似,用户进行的各种操作,也会产生事件。程序员同样可以给事件关联上处理函数(处理的逻辑),当事件触发的时候,就能够执行到对应的代码。
事件本身是操作系统提供的机制,Qt 也同样把操作系统事件机制进行了封装,拿到了Qt 中,但是由于事件对应的代码编写起来不是很方便,所以 Qt 对于事件机制又进行了进一步的封装,就得到了信号槽。信号槽就是对于事件的进一步封装,事件是信号槽的底层机制。
事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用⼀个对象来表示一个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件是在用户操作时发出,如键盘事件、鼠标事件等,另一些事件则是由系统本身自动发出,如定时器事件。常见的 Qt 事件如下:

常见事件描述:
| 事件名称 | 描述 |
| 鼠标事件 | 鼠标左键、鼠标右键、鼠标滚轮,鼠标的移动,鼠标按键的按下和松开 |
| 键盘事件 | 按键类型、按键按下、按键松开 |
| 定时器事件 | 定时时间到达 |
| 进入离开事件 | 鼠标的进入和离开 |
| 滚轮事件 | 鼠标滚轮滚动 |
| 绘屏事件 | 重绘屏幕的某些部分 |
| 显示隐藏事件 | 窗口的显示和隐藏 |
| 移动事件 | 窗口位置的变化 |
| 窗口事件 | 是否为当前窗口 |
| 大小改变事件 | 窗口大小改变 |
| 焦点事件 | 键盘焦点移动 |
| 拖拽事件 | 用鼠标进行拖拽 |
2. 事件的处理
事件处理一般常用的方法为:重写相关的 Event 函数。
在 Qt 中,几乎所有的 Event 函数都是虚函数,所以可以重新实现。如:在实现鼠标的进入和离开事件时,直接重新实现 enterEvent() 和 leaveEvent() 即可。enterEvent() 和 leaveEvent() 函数原型如下:


示例1:处理鼠标进入和离开
1、新建 Qt 项目,基类选择 QWidget,同时勾选 UI 界面文件,如下图示;

2、设计 UI 文件,如下图示;

3、这里需要创建 QLabel 的子类,重写 enterEvent 和 leaveEvent,在项目中新添加一个类:MyLabel;
- 先选中项目名称 enterEventAndleaveEvent,点击鼠标右键,选择 add new ... ,弹出如下对话框:

4、选择:Choose .... ,弹出如下界面:

5、此时项目中会新添加以下两个文件:

6、要想重写父类的函数,就需要确保你这边写的函数名字和函数的参数列表都完全一致(形参名无所谓),为了防止单词拼写错误,我们可以在帮助文档中查找对应的内容;

7、点击 "显示" 之后,出现如下内容:


8、复制 enterEvent() 和 leaveEvent() ,粘贴在项目文件 "mylabel.h" 中;

9、重写 enterEvent() 和 leaveEvent() 方法;

10、上述代码,虽然重写了这俩函数,但是还是有点问题。运行程序,我们会发现鼠标进入和移出界面上没有一点反应。这是因为当前在界面上创建的这个 label 其实是 QLabel,不是咋们自己写的 Label,咋们必须要确保界面上的这个 label 是一个咋们自己定义的 Label 类的实例,程序才会执行到。解决办法也很简单,在 UI 文件中选中 Label,右键 ------> 提升为...

11、当点击 "提升为... " 之后,弹出如下对话框:


12、修改基类:


13、执行效果如下:当鼠标进入设计好的标签之后,就会在应用程序输出栏中打印:鼠标进入

示例2:当鼠标点击时,获取对应的坐标值;
- 鼠标左键点击时,打印对应的坐标值,鼠标右键点击时,打印基于屏幕的坐标
mousePressEvent 这个函数,按下左键、右键、滚轮都能触发,有的鼠标还带有前进后退侧键,也是可以触发的;但是还有的鼠标,有着更多的按键,这就不一定能触发了~
1、在上述示例的基础上,在 mylabel.h 中声明 mousePressEvent() 方法;

2、在 mylabel.cpp 中重写 mousePressEvent() 方法;

实现效果如下:

3. 按键事件
Qt 中的按键事件是通过 QKeyEvent 类来实现的。当键盘上的按键被按下或者被释放时,键盘事件便会触发。在帮助文档中查找 QKeyEvent 类如下:

查找按键事件中所有的按键类型:在帮助文档中输入:Qt::Key,如下图:

3.1 单个按键
示例:当某个按键被按下时,输出:某个按键被按下了;
1、新建项目,在头文件 "widget.h" 中声明虚函数 keyPressEvent():

2、在 "widget.cpp" 文件中重写 keyPressEvent() 虚函数:

实现效果如下:

3.2 组合按键
在 Qt 助手中搜索:Qt::KeyboardModifier,如下图示:

Qt::KeyboardModifier 中定义了在处理键盘事件时对应的修改键。在 Qt 中,键盘事件可以与修改键一起使用,以实现一些复杂的交互操作。KeyboardModifier 中修改键的具体描述如下:
| Qt::NoModifier | 无修改键 |
| Qt::ShiftModifier | Shift 键 |
| Qt::ControlModifier | Ctrl 键 |
| Qt::AltModifier | Alt 键 |
| Qt::MetaModifier | Meta键(在Windows上指Windows键,在macOS上指Command键) |
| Qt::KeypadModifier | 使用键盘上的数字键盘进行输⼊时,Num Lock键处于打开状态 |
| Qt::GroupSwitchModifier | 用于在输入法 组之间 切换 |
示例:

实现效果如下:

4. 鼠标事件
在 Qt 中,鼠标事件是用 QMouseEvent 类来实现的。当在窗口中按下鼠标或者移动鼠标时,都会产生鼠标事件。
利用 QMouseEvent 类可以获取鼠标的哪个键被按下了以及鼠标的当前位置等信息。在 Qt 帮助文档中查找 QMouseEvent类 如下图示:


4.1 鼠标单击事件
在 Qt 中,鼠标按下是通过虚函数 mousePressEvent() 来捕获的。mousePressEvent() 函数原型如下:
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
鼠标左右键及滚轮的表示如下:
- Qt::LeftButton 鼠标左键
- Qt::RightButton 鼠标右键
- Qt::MidButton 鼠标滚轮
示例:鼠标左键 + 右键 + 滚轮
1、在 "widget.h" 头文件中声明鼠标按下事件;

2、在 "widget.cpp" 文件中重新实现 mousePressEvent() 函数;

实现效果如下:

4.2 鼠标释放事件
鼠标释放事件是通过虚函数 mouseReleaseEvent() 来捕获的。mouseReleaseEvent() 函数原型如下:
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
示例:鼠标左键释放
1、在 "widget.h" 头文件中声明鼠标释放事件;

2、在 "widget.cpp" 文件中重新实现 mouseReleaseEvent() 函数;

实现效果如下:

4.3 鼠标双击事件
鼠标双击事件是通过虚函数:mouseDoubleClickEvent() 来实现的。mouseDoubleClickEvent() 函数原型如下:
[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
示例:鼠标左键双击
1、在 "widget.h" 头文件中声明鼠标双击事件;

2、在 "widget.cpp" 文件中重新实现 mouseDoubleClickEvent() 函数;

实现效果如下:

4.4 鼠标移动事件
鼠标移动事件是通过虚函数:mouseMoveEvent() 来实现的。同时为了实时捕获鼠标位置信息,需要通过函数 setMouseTracking() 来追踪鼠标的位置。
mouseMoveEvent()函数原型如下:
- [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
setMouseTracking()函数原型如下:
- void setMouseTracking(bool enable)
说明:
鼠标移动不同于鼠标按下。随便移动一下鼠标,就会产生出大量的鼠标移动事件。当你进行捕获事件的时候,尤其是在这里在进行一些复杂逻辑的时候,程序负担就很重,很容易产生卡顿之类的情况。
Qt 为了保证程序的流畅性,默认情况下不会对鼠标移动进行追踪,鼠标移动的时候不会调用 mouseMoveEvent。除非显示告诉 Qt 要追踪鼠标位置。
setMouseTracking() 函数默认是 false,需要设置为 true,才能实时捕获鼠标位置信息。否则只有当鼠标按下时才能捕获其位置信息。
示例:
1、在 "widget.h" 头文件中声明鼠标移动事件;

2、在 "widget.cpp" 文件中重新实现 mouseMoveEvent() 函数;

执行效果:

4.5 滚轮事件
在 Qt 中,鼠标滚轮事件是通过 QWheelEvent 类来实现的。滚轮滑动的距离可以通过 delta() 函数获取。delta() 函数原型如下:
int QGraphicsSceneWheelEvent::delta() const
其中返回值代表滚轮滑动的距离。正数表示滚轮相对于用户向前滑动,负数表示滚轮相对于用户向后滑动。
示例:
1、在 "widget.h" 头文件中声明鼠标滚轮事件;

2、在 "widget.cpp" 文件中重新实现 wheelEvent() 函数;

执行效果:

5. 定时器
Qt 中在进行窗口程序的处理过程中,经常要周期性的执行某些操作,或者制作一些动画效果,使用定时器就可以实现。所谓定时器就是在间隔一定时间后,去执行某⼀个任务。定时器在很多场景下都会使用到,如弹窗自动关闭之类的功能等。
Qt中的定时器分为 QTimerEvent 和 QTimer 这2个类:
- QTimerEvent类 用来描述一个定时器事件。在使用时需要通过 startTimer() 函数来开启一个定时器,这个函数需要输入一个以毫秒为单位的整数作为参数来表明设定的时间,它返回的整型值代表这个定时器。当定时器溢出时(即定时时间到达)就可以在 timerEvent() 函数中获取该定时器的编号来进行相关操作。
- QTimer类 来实现一个定时器,它提供了更高层次的编程接口,如:可以使用信号和槽,还可以设置只运行一次的定时器。
5.1 QTimerEvent 类
示例1:在UI界面上放置两个 Label 控件,⼀个让其1秒数字累加⼀次,⼀个让其2秒数字累加⼀次。
1、新建项目,在UI界面文件放置两个 Label 控件;

2、在 "widget.h" 头文件中声明 timerEvent() 函数,并定义两个整型变量;

3、在 "widget.cpp" 文件中重写 timerEvent() 函数;

实现效果如下:

5.2 QTimer 类
示例:在UI界面放置一个 Label 标签,两个按钮,分别是 "开始" 和 "停止" ,当点击 "开始" 按钮时,开始每隔1秒计数⼀次,点击 "停止" 按钮时,暂停计数。
1、设计 UI 界面如下:

2、在 "widget.cpp" 文件中实现对应功能;

实现效果如下:

5.3 获取系统日期及时间
在 Qt 中,获取系统的日期及实时时间可以通过 QTimer 类 和 QDateTime类。
QDateTime类 提供了字符串格式的时间。字符串形式的时间输出格式由 toString() 方法中的 format 参数列表决定,可用的参数列表如下:

示例:获取系统日期及实时时间;
1、设计UI界面文件;放置⼀个 Label控件,用来显示日期及时间,放置两个按钮:"开始" 和 "停止" ;

2、在 "widget.h" 头文件中声明更新时间的槽函数;

3、在 "widget.cpp" 文件中实现对应功能;

实现效果如下:

6. 事件分发器
6.1 概述
在 Qt 中,事件分发器(Event Dispatcher) 是⼀个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject类 或 QObject类 本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。
6.2 事件分发器工作原理
在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event() 函数。所有的事件都会进入到这个函数里面,那么我们处理事件就要重写这个 event() 函数。event() 函数本身不会去处理事件,而是根据 事件类型(type值)调用不同的事件处理函数。事件分发器就是工作在应用程序向下分发事件的过程中,如下图:

如上图,事件分发器用于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e) 函数来实现。其返回值为布尔类型,若为 ture,代表拦截,不向下分发。
Qt 中的事件是封装在 QEvent类 中,在 Qt 助手中输入 QEvent 可以查看其所包括的事件类型,如下图示:


示例:
1、在 "widget.h" 头文件中声明 鼠标点击事件 和 事件分发器;如下图示:

2、在 "widget.cpp" 文件中实现 鼠标点击事件 和 拦截事件;

执行结果如下:
7. 事件过滤器
在 Qt 中,一个对象可能经常要查看或拦截另外一个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。通过前面学习过的知识,我们已经知道,Qt 创建了 QEvent事件 对象之后,会调用QObject 的 event()函数 处理事件的分发。显然,我们可以在 event()函数 中实现拦截的操作。由于 event()函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个event()函数。这当然相当麻烦,更不用说重写 event()函数还得小心一堆问题。好在 Qt 提供了另外一种机制来达到这一目的:事件过滤器。
事件过滤器是在应用程序分发到 event事件分发器 之前,再做⼀次更高级的拦截。如下图示:

事件过滤器的一般使用步骤:
- 安装事件过滤器;
- 重写事件过滤器函数:eventfilter() 。
示例:
1、新建 Qt 项目,基类选择 QWidget,同时勾选 UI 界面文件,如下图示;

2、设计 UI 文件,如下图示;

3、在项目新添加⼀个类:MyLabel;
先选中项目名称 QEvent,点击鼠标右键,选择 add new ... ,弹出如下对话框:

4、选择:Choose .... ,弹出如下界面:

5、此时项目中会新添加以下两个文件:

6、在 UI 文件中选中 Label,右键 ------> 提升为...

7、当点击 "提升为... " 之后,弹出如下对话框:

8、在 "mylabel.h" 中声明 鼠标点击事件 和 事件分发器;

9、在 "mylabel.cpp" 文件中实现鼠标点击事件和事件分发器;

10、在 "widget.h" 头文件中声明事件过滤器函数;

11、在 "widget.cpp" 文件中实现事件过滤器的两个步骤;

执行结果如下所示:
相关文章:
Qt 系统相关 - 事件
目录 1. 事件介绍 2. 事件的处理 示例1:处理鼠标进入和离开 示例2:当鼠标点击时,获取对应的坐标值; 3. 按键事件 3.1 单个按键 3.2 组合按键 4. 鼠标事件 4.1 鼠标单击事件 4.2 鼠标释放事件 4.3 鼠标双击事件 4.4 鼠标…...
Ubuntu最小化命令行系统 安装GUI 远程桌面
Ubuntu 服务器 安装GUI 更新、升级 sudo apt update && sudo apt upgrade安装桌面环境 sudo apt install taskselsudo apt install ubuntu-desktop安装显示登录管理器 sudo apt install lightdm安装 lightdm 时系统会让选择默认的显示管理器,选择lightd…...
Web前端:CSS篇(二)背景,文本,链接
CSS 背景 背景颜色 background-color 属性定义了元素的背景颜色. 页面的背景颜色使用在body的选择器中: body {background-color:#b0c4de;} CSS中,颜色值通常以以下方式定义: 十六进制 - 如:"#ff0000"RGB - 如:"rgb(255,0…...
ubuntu 24.04 软件源配置,替换为国内源
ubuntu 默认的官网源下载速度非常慢,新装 ubuntu 系统首先把 apt 软件源替换成国内源。 1、使用软件和更新设置国内源 打开软件和更新,选择位于中国的服务器: 外链图片转存失败,源站可能有防盗链机制,建议将图片保存…...
【Java 并发编程】(三) 从CPU缓存开始聊 volatile 底层原理
并发编程 三大问题 在并发编程中,原子性、有序性和可见性是三个重要的问题,解决这三个问题是保证多线程程序正确性的基础。原子性: 指的是一个操作不可分割, 要么全部执行完成, 要么不执行, 不存在执行一部分的情况.有序性: 有序性是指程序的执行顺序与…...
YOLOV8网络结构|搞懂Backbone-Conv
参数量计算: (输入通道*w)*(输出通道*w)*k^2+(输出通道*w)*2 w是模型缩放里面的width - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 输出通道c2=64,k=3,s=2 P1/2 特征图变小一半 先定义算子层 再搭一个forward前向传播 class Conv(nn.Module):"""Standard convo…...
Elasticsearch Nested类型详解与实战
Elasticsearch(简称ES)是一个基于Lucene的全文搜索引擎,它提供了强大的搜索能力以及对数据的高效索引和查询。在ES中,数据通常以JSON格式存储,并且可以采用多种数据类型。其中,nested类型是一种特殊的对象数…...
网络编程,网络协议,UDP协议
网络: 1.协议:通信双方约定的一套标准 2.国际网络通信协议标准: 1.OSI协议: 应用层 发送的数据内容 表示层 数据是否加密 会话层 是否建立会话连接 传输层 …...
每日一题——第六十三题
题目:判断一个数是否为合数 #include <stdio.h> #include <stdbool.h> // 为了使用bool类型 // 函数声明,用于判断是否为合数 bool isComposite(int x); int main() { int x; printf("请输入一个正整数: "); scanf(&quo…...
人工智能算法,图像识别技术;基于大语言模型的跨境商品识别与问答系统;图像识别
目录 一 .研究背景 二,大语言模型介绍 三,数据采集与预处理 商品识别算法 四. 跨境商品问答系统设计 五.需要源码联系 一 .研究背景 在当今全球化的背景下,跨境电商行业迅速发展,为消费者提供了更广泛的购物选择和更便利的购物方式。然而…...
数据库系统 第18节 数据库安全
数据库安全是确保数据库管理系统(DBMS)中存储的数据的保密性、完整性和可用性的过程。以下是一些关键的数据库安全措施: 用户身份验证(Authentication): 这是确定用户或系统是否有权访问数据库的第一步。通…...
Golang | Leetcode Golang题解之第338题比特位计数
题目: 题解: func countBits(n int) []int {bits : make([]int, n1)for i : 1; i < n; i {bits[i] bits[i&(i-1)] 1}return bits }...
【Python变量简析】
Python变量简析 在 Python 中,变量是用于存储和操作数据的命名内存位置。变量的概念类似于代数中的方程变量,比如对于方程式 y x * x ,x 就是变量。 Python 变量具有以下特点: 变量名可以由字母、数字和下划线组成,…...
智慧零售模式下物流优化与开源AI智能名片S2B2C商城系统的深度融合
摘要:在数字化浪潮的推动下,智慧零售模式正逐步成为零售业的新常态。该模式通过深度融合物联网、大数据、人工智能等先进技术,实现了线上线下无缝衔接,为消费者提供了更加便捷、个性化的购物体验。物流作为智慧零售的重要支撑&…...
socket和websocket 有什么区别
Socket 和 WebSocket 都用于网络通信,但它们的用途、协议、以及使用方式有所不同。以下是两者的主要区别: ### 1. **基础协议** - **Socket**: - Socket 是网络通信的一个抽象概念,通常基于传输层协议,如 TCP(…...
亿玛科技:TiDB 6.1.5 升级到 7.5.1 经验分享
作者: foxchan 原文来源: https://tidb.net/blog/6e628afd 为什么要升级? 本次升级7.5的目的如下: 1、tidb有太多的分区表需要归档整理。7.5版本这个功能GA了。 2、之前集群tikv节点的region迁移过慢,影响tikv节…...
8.16-ansible的应用
ansible ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。 格式 ansible 主机ip|域名|组名|别名 -m ping|copy|... 参数 1.ping模块 m0 # 查看有没有安装epel [rootm0 ~]#…...
相似度计算方法-编辑距离 (Edit Distance)
定义 编辑距离(Edit Distance),也称为Levenshtein距离,是一种衡量两个字符串相似度的方法。它定义为从一个字符串转换为另一个字符串所需的最少单字符编辑操作次数,这些操作包括插入、删除或替换一个字符。 计算方法 …...
初识FPGA
大学的时候有一门verilog语言,觉得很难,不愿学。有学习套件是黑金的一块FPGA开发板,可能当时点灯和点数码管了。全都忘了。 今项目需要,使用FPGA中的ZYNQ,需要c语言开发,随即开始学习相关知识。 ZYNQ内部…...
探索 JavaScript:从入门到精通
目录 1. JavaScript 的介绍与基础 示例:弹出欢迎信息 JavaScript,作为网络时代最流行的脚本语言之一,赋予了网页生动活泼的动态功能。无论是新手还是经验丰富的开发者,掌握 JavaScript 的核心概念和技能都是开启网络编程之门的钥…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
