在QGraphicsView中精确地以鼠标为锚缩放图片
在pyqt中以鼠标所在位置为锚点缩放图片-CSDN博客中的第一个示例中,通过简单设置:
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
使得QGraphicsView具有了以鼠标为锚进行缩放的功能。但是,其内部应当是利用了滚动条的移动来实现的,类似于下面这样:
// 连接滚动条信号,实时更新场景偏移值,在图片放大到超过视图区域时,
// 继续放大图片,鼠标位置对应的图片上的点不会在视图区移动
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, [this](int value) {
sceneOffset.setX(-value); // 注意负号
});connect(verticalScrollBar(), &QScrollBar::valueChanged, this, [this](int value) {
sceneOffset.setY(-value); // 注意负号
});
所以,当图片项缩小到视图范围以内,滚动条不再起作用时,就丧失了以鼠标为锚缩放图片的特性。同一篇文章的第二个示例用QLabel作为图片容器实现了严格的以鼠标为锚缩放图片的效果,但正如该文所指出的,涉及图片平移缩放等各种变换的程序,最佳的图片容器仍然是QGraphicsView,那么,如何在QGraphicsView中实现精确的以鼠标为锚缩放图片的效果呢?
这个问题实际上比以QLabel作为图片容器要复杂一些,因为以QLabel作为图片容器时,只有一个坐标系统,也就是以QLabel左上角为原点的坐标系统,容器中的所有图片的位置设置都相对于QLabel左上角计算。但是,在QGraphicsView框架中,却涉及三个坐标系统:
1、视图坐标系统(QGraphicsView的坐标系统):以QGraphicsView容器左上角为原点,并且从不变化。
2、场景坐标系统(QGraphicsScene的坐标系统):QGraphicsScene代表一个没有边界、没有大小的舞台(画布),它的原点是给QGraphicsItem定位的逻辑原点,在QGraphicsView的坐标系统中的值可能随着变换操作发生变化。在没有对场景做任何缩放和移动等变换的时候,这个逻辑原点等于QGraphicsView坐标系统中的原点坐标(0,0)。
3、图片项坐标系统(QGraphicsItem的坐标系统):在QGraphicsView框架中,图片等各种图形元素是在不同的QGraphicsItem中加载的,也就是说,一张图片就是一个QGraphicsItem(具体来说位图可以用QGraphicsPixmapItem来加载)。QGraphicsPixmapItem中的图片也有一个以自身左上角为原点的像素坐标系统,这个原点相对于场景坐标系统原点的坐标由QGraphicsItem::setPos()方法设置,可以通过QGraphicsItem::pos()方法取得。无论场景如何移动和变换,只要图形本身没有在场景上发生过位置变换,QGraphicsItem::pos()方法的返回值都是不变的。
如果要将QGraphicsItem的位置设置为视图坐标系统中的点(x,y),需要以下步骤:
1、定义想要放置Item的点target_view_point,其在视图坐标系统中的坐标为 (x,y)。
2、使用 QGraphicsView::mapToScene() 方法将这个视图坐标转换为场景坐标 scene_point。无论对视图做了什么变换(例如缩放和平移等),QGraphicsView框架都会自行处理,只要(x,y)不变,scene_point也不会发生变化。
3、使用 QGraphicsItem::setPos() 方法将QGraphicsItem左上角放置在转换后的场景坐标 scene_point。
示例代码如下:
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem
from PyQt5.QtCore import Qt, QPointif __name__ == '__main__':app = QApplication([])scene = QGraphicsScene()view = QGraphicsView(scene)view.setWindowTitle("Place Item at View Coordinate")# 程序窗体将显示在屏幕(100, 100)的位置,这个点也就是视图坐标系的原点(0, 0)view.setGeometry(100, 100, 400, 300)# 您想要放置Item的视图坐标view_x = 50view_y = 75# 视图坐标系中的坐标(50, 75),屏幕坐标系中的坐标(150, 175)target_view_point = QPoint(view_x, view_y)# 将视图坐标转换为场景坐标,这个值由QGraphicsView框架计算得出,自己难以简单计算scene_point = view.mapToScene(target_view_point)# 创建一个QGraphicsRectItemrect = QGraphicsRectItem(0, 0, 50, 50)# 将QGraphicsRectItem左上角放置在转换后的场景坐标,也就放置在视图坐标系中的坐标(50, 75)处rect.setPos(scene_point)scene.addItem(rect)view.show()app.exec_()
根据对上述坐标系统之间的关系的理解,可以通过以下步骤实现QGraphicsView中以鼠标为锚点缩放图片的效果(仅考虑简单的平移缩放变换,图片项为pixmapItem ,缩放因子为zoomFactor,用C++的形式写伪代码):
1、获取鼠标在缩放前图片上的场景坐标:
1.1、将鼠标的视图坐标 mousePos 转换为场景坐标
mouseScenePos = mapToScene(mousePos.toPoint());
1.2、计算 mouseScenePos 相对于 pixmapItem 缩放前的场景坐标 pixmapItem->pos() 的偏移量:
offsetToMouse = mouseScenePos - pixmapItem->pos();
应当说明的是,这一步还有一个更健壮、更安全、适用能力更强、直接利用Qt Graphics View 框架内部的坐标转换机制的做法:
offsetToMouse = pixmapItem->mapFromScene(mouseScenePos);
QGraphicsItem::mapFromScene(scenePoint): 这个函数的作用是将一个点从场景 (Scene) 的坐标系转换到该图形项 (item) 的局部坐标系。它考虑了该图形项自身以及其所有父项的完整变换(包括平移、缩放、旋转),返回值是这个点相对于该图形项左上角原点 (0,0) 的坐标。mapFromScene() 会正确处理图形项的平移、旋转和缩放。如果手动对 item 调用了 setRotation() 或 setScale(),或者它的父项有变换,那么简单的 scenePoint - item->pos() 就会得到错误的结果,而 mapFromScene() 仍然是正确的。因此,除非是确信极为简单的只有平移变换且不存在父项变换的情况,才推荐使用scenePoint - item->pos()手工计算的方式将场景坐标转换为图形项的局部坐标。
2、计算缩放后鼠标在图片上的场景坐标应该在的位置:
2.1、由于缩放是以 pixmapItem 的左上角为原点进行的(默认情况),那么 offsetToMouse 这个向量也应该被缩放 zoomFactor 倍。因此,缩放后鼠标在图片上的目标场景坐标应该是:
targetMouseScenePos = pixmapItem->pos() + offsetToMouse * zoomFactor;
注意,此时 pixmapItem->pos()的值与缩放前相比并未改变。
3、计算 pixmapItem 需要移动的偏移量:
为了使缩放后鼠标的目标场景坐标 targetMouseScenePos 与缩放前的鼠标场景坐标 mouseScenePos 在视图中的位置保持一致,pixmapItem 需要移动一定的距离。这个移动的距离按下式计算:
deltaMove = mouseScenePos - targetMouseScenePos;
4、更新 pixmapItem 的位置:
将 pixmapItem 的当前位置加上这个 deltaMove:
pixmapItem->setPos(pixmapItem->pos() + deltaMove);
根据上述步骤实现的在QGraphicsView中以鼠标为锚点缩放图片的完整Python示例如下:
from PyQt5.QtWidgets import (QApplication, QMainWindow, QGraphicsView, QGraphicsScene, QGraphicsItem,QPushButton, QVBoxLayout, QFileDialog, QWidget
)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt, QPointF
import sysclass ImageViewer(QGraphicsView):def __init__(self, parent=None):super().__init__(parent)self.scene = QGraphicsScene(self)self.setScene(self.scene)# 保存原始图片和缩放信息self.original_pixmap = None # 原始图片self.pixmap_item = None # 场景中的图片项self.scale_factor = 1.0 # 缩放因子self.scene_offset = QPointF(0, 0) # 场景在视图中的偏移量# 设置视图属性self.setDragMode(QGraphicsView.ScrollHandDrag)self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)# 固定视图大小self.setFixedSize(600, 600)def add_image(self, image_path):"""加载图片并显示"""self.scene.clear()self.original_pixmap = QPixmap(image_path)if self.original_pixmap.isNull():return# 初始化显示self.scale_factor = 1.0self.pixmap_item = self.scene.addPixmap(self.original_pixmap)self.pixmap_item.setTransformationMode(Qt.SmoothTransformation)# 计算初始缩放以适应视图view_size = self.size()scale = min(view_size.width() / self.original_pixmap.width(),view_size.height() / self.original_pixmap.height())# 应用初始缩放self.scale_factor = scalescaled_pixmap = self.original_pixmap.scaled(self.original_pixmap.size() * scale,Qt.KeepAspectRatio,Qt.SmoothTransformation)self.pixmap_item.setPixmap(scaled_pixmap)# 设置图片项可移动self.pixmap_item.setFlag(QGraphicsItem.ItemIsMovable) # 计算居中位置self.scene_offset = QPointF((view_size.width() - scaled_pixmap.width()) / 2,(view_size.height() - scaled_pixmap.height()) / 2)self.setSceneRect(0, 0, view_size.width(), view_size.height())self.pixmap_item.setPos(self.scene_offset)def wheelEvent(self, event):"""实现精确地以鼠标位置为锚点的缩放"""if not self.pixmap_item:returnself.pixmap_item.setCursor(Qt.ArrowCursor)# 获取鼠标相对于图片的位置mouse_pos = event.pos()mouseScenePos = self.mapToScene(mouse_pos)itemScenePos = self.pixmap_item.pos()# 下面注释掉的一行是更健壮适应更复杂的变换情况的做法# offsetToMouse = self.pixmap_item.mapFromScene(mouseScenePos)offsetToMouse = mouseScenePos - itemScenePos# 计算缩放因子if event.angleDelta().y() > 0:zoom_factor = 1.15else:zoom_factor = 1 / 1.15# 限制缩放倍数在0.1到10之间 tmp_scale_factor = self.scale_factor * zoom_factorif tmp_scale_factor > 10:zoom_factor = 10 / self.scale_factorelif tmp_scale_factor < 0.1:zoom_factor = 0.1 / self.scale_factor# 更新总缩放倍数self.scale_factor *= zoom_factor# 缩放图片scaled_pixmap = self.original_pixmap.scaled(self.original_pixmap.size() * self.scale_factor,Qt.KeepAspectRatio,Qt.SmoothTransformation)# 计算鼠标位置相对于图片的偏移量变化 targetMouseScenePos = itemScenePos + offsetToMouse * zoom_factordeltaMove = mouseScenePos - targetMouseScenePos# 更新图片和位置self.pixmap_item.setPixmap(scaled_pixmap)self.pixmap_item.setPos(self.pixmap_item.pos() + deltaMove)class MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("以鼠标为锚缩放图片示例")self.setGeometry(100, 100, 800, 600)# 创建主窗口布局central_widget = QWidget()self.setCentralWidget(central_widget)layout = QVBoxLayout(central_widget)# 创建 QGraphicsViewself.graphics_view = ImageViewer(self)layout.addWidget(self.graphics_view)# 创建按钮self.load_button = QPushButton("加载图片")self.load_button.clicked.connect(self.open_file_dialog)layout.addWidget(self.load_button)def open_file_dialog(self):"""打开文件对话框选择图片"""file_path, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "图片文件 (*.png *.jpg *.jpeg *.bmp)")if file_path:self.graphics_view.add_image(file_path)if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()# 禁用最大化按钮window.setWindowFlags(window.windowFlags() & ~Qt.WindowMaximizeButtonHint)window.show()sys.exit(app.exec_())
运行效果如下
本文最后一个问题:图片缩放后,如果要从鼠标在视图中的坐标获取其在未经缩放的原始图片像素坐标中的坐标,该怎么做?其实很简单:
1、将鼠标坐标(视图鼠标事件中事件发生的位置,都是以视图坐标系确定的)转换为场景坐标系中的坐标,记为p1;
2、确定图片项的坐标系原点在场景中的坐标,记为p2;
3、p1-p2,即鼠标位置在图片项坐标系中的坐标,记为p3。图片项实际上就是经过缩放的图片;
4、将p3除以缩放倍数。
只考虑pixmapItem通过scaleFactor进行了均匀缩放的情况,具体的转换函数代码如下:
def viewPosToOriginalImgPos(self, viewPos: QPointF, scaleFactor: float) -> QPointF:scenePos = self.mapToScene(viewPos)itemPosInScene = self.pixmapItem.pos()posInItem = scenePos - itemPosInSceneoriginalImgX = posInItem.x() / scaleFactororiginalImgY = posInItem.y() / scaleFactorreturn QPointF(originalImgX, originalImgY)
如果x方向与y方向的缩放比例不同,可以通过
self.pixmapItem.transform().m11()
# 获取 x 方向的缩放,
self.pixmapItem.transform().m22()
# 获取 y 方向的缩放。
取得不同方向上的缩放倍数,从而将鼠标位置转换为正确的原始图片像素坐标系中的坐标。
相关文章:
在QGraphicsView中精确地以鼠标为锚缩放图片
在pyqt中以鼠标所在位置为锚点缩放图片-CSDN博客中的第一个示例中,通过简单设置: self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) 使得QGraphicsView具有了以鼠标为锚进行缩放的功能。但是,其内部应当是利用了滚动条的移动来…...
【Python数据驱动决策】数据分析与可视化全流程实战指南
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比二、实战演示环境配置要求核心代码实现案例1:销售数据清洗案例2:月度销售趋势分析案例3:产品关联分析(热力图)运行结果验证三、性能对…...
报错解决:ModuleNotFoundError: No module named ‘triton.ops‘
报错原因:2024.5.21之后, triton.ops 被移动到另一个工程 triton-lang/kernels中。 参考链接:官方解释 解决方案:换用2024.5.21之前发布的版本。 pip3 install triton2.3.0...
相机-IMU联合标定:相机-IMU外参标定
文章目录 📚简介🚀标定工具kalibr🚀标定数据录制🚀相机-IMU外参标定📚简介 在 VINS(视觉惯性导航系统) 中,相机-IMU外参标定 是确保多传感器数据时空统一的核心环节,其作用可概括为以下关键点: 坐标系对齐(空间同步),外参误差会导致视觉特征点投影与IMU预积…...
Qt C++数据库实验
一、实验目的和要求 1、掌握Qt中数据库SQL类数据库的查询、插入和更新操作。 2、熟悉Qt界面设计中常用的控件。 3、了解数据库相关类。 二、实验内容 1、设计一个数据库操作软件,完成数据库的相关操作。 2、建立按钮的信号与槽函数,实现点击按钮进…...
相机-IMU联合标定:IMU标定
文章目录 📚 简介🚀标定工具安装📌 IMU标定工具 code_utils📌 IMU标定工具 imu_utils:🚀标定数据录制🚀IMU标定📚 简介 在 VINS(Visual-Inertial Navigation System,视觉惯性导航系统) 中,IMU标定 是确保系统高精度运行的关键环节。IMU(惯性测量单元)本身…...
榕壹云信用租赁系统:基于ThinkPHP+MySQL+UniApp的全链路免押租赁解决方案
信用租赁时代的全流程数字化革新 随着共享经济与信用体系的深度融合,传统租赁行业正面临效率与信任的双重挑战。榕壹云信用租赁系统依托ThinkPHP高性能框架、MySQL数据库与UniApp跨平台开发技术,构建了一套覆盖设备租赁全生命周期的数字化解决方案。通过整合多因子身份认证、…...
C语言中的指针详解
指针是C语言中非常强大且复杂的特性之一,它为我们提供了更灵活的内存管理方式,使得程序能够直接操作内存,提升效率和性能。尽管指针非常强大,但如果不理解它的概念和使用方式,很容易出现错误。因此,理解指针…...
NIPS2021 | 视觉 Transformer 的有趣特性
Intriguing Properties of Vision Transformers 摘要-Abstract引言-Introduction相关工作-Related Work视觉Transformer的有趣特性-Intriguing Properties of Vision Transformers视觉Transformer对遮挡具有鲁棒性吗?-Are Vision Transformers Robust to Occlusions…...
贪心算法-2208.将数组和减半的最小操作数-力扣(LeetCode)
一、题目解析 这里要注意恰好这个字眼,说明对任意数减小一半是不需要向上取整的,所以我们需要定义double类型的数据。 二、算法解析 我们需要将数组和减小为一半的次数最少,所以根据贪心算法,我们需要取数组中最大的数进行减半操…...
如何搭建spark yarn 模式的集群集群。
下载 App 如何搭建spark yarn 模式的集群集群。 搭建Spark on YARN集群的详细步骤 Spark on YARN模式允许Spark作业在Hadoop YARN资源管理器上运行,利用YARN进行资源调度。以下是搭建步骤: 一、前提条件 已安装并配置好的Hadoop集群(包括HDF…...
嵌入式开发面试典型编程题解析:排序算法、指针操作、字符处理、递归原理等基础原理的深度解析。
在嵌入式开发面试中,编程题是常见的考察形式,旨在检验求职者对基础编程知识的掌握和应用能力。以下是几道典型的嵌入式面试编程题及详细解析,帮助新手逐步理解和掌握相关知识点。 一、用交换法对学生成绩降序排序 题目描述 在嵌入式系统开…...
DeepSeek+即梦:AI视频创作从0到1全突破
目录 一、开启 AI 视频创作大门:前期准备1.1 注册与登录1.2 熟悉工具界面1.3 硬件与网络要求 二、用 DeepSeek 构思视频脚本2.1 明确创作主题与目标2.2 编写优质提示词2.3 生成并优化脚本 三、即梦 AI 实现画面生成3.1 文生图基础操作3.2 调整参数提升画质3.3 保持人…...
npm init、换源问题踩坑
文章目录 一、 问题复现二、问题解决 一、 问题复现 成功安装nodejs 以及 npm 版本如下: > node -v > v20.18.0 > npm -v > 10.8.2使用 npm init 命令时延时过长,考虑换源,使用指令 npm config set registry https://registr…...
TRex 控制台命令解析
TRex 是一种高性能的网络测试工具,用于生成和分析网络流量。以下是对这些命令的简要解释: 一、help Console Commands(控制台命令) capture:管理 PCAP 捕获。debug:用于开发的内部调试器。events&#x…...
【Shell 脚本入门】轻松上手的实战指南
🌈 个人主页:Zfox_ 🔥 系列专栏:Shell脚本编程 目录 一:🔥 什么是 Shell 🦋 常见的 Shell 类型 二:🔥 什么是 Shell 脚本 🦋 Shell 脚本规则🦋 第…...
数据结构*栈
栈 什么是栈 这里的栈与我们之前常说的栈是不同的。之前我们说的栈是内存栈,它是JVM内存的一部分,用于存储局部变量、方法调用信息等。每个线程都有自己独立的栈空间,当线程启动时,栈就会被创建;线程结束,…...
零基础制作Freertos智能小车(教程非常简易)持续更新中....
从现开始,将陆续推出各类简单的DIY电子设计,由简入深,将自己的制作过程全部分享出来,巩固自己知识的同时希望借此机会认识更多喜欢电子设计的小伙伴。 本次小车的主控芯片采用stm32f103c8t6,主要是便宜好用&am…...
Leetcode - 双周赛155
目录 一,3527. 找到最常见的回答二,3528. 单位转换 I三,3529. 统计水平子串和垂直子串重叠格子的数目四,3530. 有向无环图中合法拓扑排序的最大利润 一,3527. 找到最常见的回答 题目列表 本题是一道模拟题࿰…...
详解RabbitMQ工作模式之工作队列模式
目录 工作队列模式 概念 特点 应用场景 工作原理 注意事项 代码案例 引入依赖 常量类 编写生产者代码 编写消费者1代码 编写消费者2代码 先运行生产者,后运行消费者 先运行消费者,后运行生产者 工作队列模式 概念 在工作队列模式中&#x…...
QGIS+mcp的安装和使用
QGISmcp的安装和使用 安装qgis_mcp 下载qgis_mcp: git clone https://github.com/jjsantos01/qgis_mcp.git安装uv uv是一个由Rust语言编写的python包管理工具,旨在提供比传统工具(如 pip)更高效的依赖管理和虚拟环境操作。 p…...
Java基础361问第16问——枚举为什么导致空指针?
我们看一段代码 public enum Color {RED, BLUE, YELLOW;public static Color parse(String color) {return null;} }public static void main() {Color color Color.parse("");// 极具迷惑性,大家日常开发肯定这么写过switch (color) {case RED:break;c…...
在 C# .NET 中驾驭 JSON:使用 Newtonsoft.Json 进行解析与 POST 请求实战
JSON (JavaScript Object Notation) 已经成为现代 Web 应用和服务之间数据交换的通用语言。无论你是开发后端 API、与第三方服务集成,还是处理配置文件,都绕不开 JSON 的解析与生成。在 C# .NET 世界里,处理 JSON 有多种选择,其中…...
CentOS7——Docker部署java服务
1、安装Docker 首先要确保系统已安装 Docker,若未安装,可以参考我的另一篇文章现在CentOS7上安装Docker,文章地址如下: CentOS7系统安装Docker教程-CSDN博客 Docker当中要安装必备的软件,比如Java运行必要的JDK&#…...
Python-Part2-集合、字典与推导式
Python-Part2-集合、字典与推导式 1. set集合 ⽆序,去掉重复数据。 set1 {1,2,3,4,5,5,4,3,2,1}print(type(set1))print(set1)set2.add(66666)set2.remove(55)#不能使用下标访问set,所以修改操作一般为remove操作 add操作2.dict 字典 字典ÿ…...
《AI大模型应知应会100篇》第39篇:多模态大模型应用:文本、图像和音频的协同处理
第39篇:多模态大模型应用:文本、图像和音频的协同处理 摘要 随着人工智能技术的发展,多模态大模型(Multimodal Large Models)已经成为AI领域的热点之一。这些模型能够同时处理文本、图像、音频等多种模态数据…...
kvm学习小结
安装相关包 安装虚拟化相关包 apt install qemu-kvm qemu-system libvirt-clients libvirt-daemon-system vlan bridge-utils 安装界面相关包 apt install xinit gdmd 配置机器允许root登录 检查cpu是否支持虚拟化 egrep -o vmx|svm /proc/cpuinfo 执行命令systemctl s…...
k8s基本概念-YAML
YAML介绍 YAML是“YAML Aint a Markup Language” (YAML不是一种置标语言)的递归缩进写,早先YAML的意思其实是:“Yet Another Markup Language”(另一种置标语言) YAML是一个类似XML、JSON的标记性语言。YAML强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义…...
wps批注线条怎么取消去掉wps批注后有竖线
wps批注线条怎么取消去掉wps批注后有竖线 问题 图片 解决方案 图片 word批注线条取消的方法: 1.打开Word文档,点击需要删除的批注。 2.然后点击工具栏“审阅”选项。 3.接着点击“接受“ 4.接受对文档所做的所有修订(H)...
深度解析算法之分治(归并)
48.排序数组 题目链接 给你一个整数数组 nums,请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。 示例 1: 输入: nums [5,2,3,1] 输出&am…...
僵尸进程是什么?
僵尸进程(Zombie Process)是指在 Unix/Linux 系统中,一个子进程已经终止,但其父进程尚未对它进行善后处理(即没有读取其退出状态),导致子进程的进程表项仍然保留在系统中。由于这个进程已经结束…...
城市群出行需求的时空分形
城市群出行需求的时空分形 原文:He, Zhengbing. “Spatial-temporal fractal of urban agglomeration travel demand.” Physica A: Statistical Mechanics and its Applications 549 (2020): 124503. 1. Introduction(引言) 城市区域的重…...
LangChain入门(二)安装开发环境
1.安装conda Conda 是一个开源的软件包管理系统和环境管理系统,用于安装多个版本的软件包及其依赖关系,并在它们之间轻松切换。 Anaconda是一个开源的Python发行版本,其包含了conda、python等软件包,numpy、pandas、scipy等科学…...
如何开展有组织的AI素养教育?
一、AI素养的定义与核心内涵 AI素养是智能时代个体适应与创新能力的综合体现,其内涵随着技术发展动态扩展,包含以下核心维度: 知识体系:理解AI基本原理(如算法、数据、算力)、技术边界及发展趋势ÿ…...
InnoDB对LRU算法的优化
标准 LRU 算法的核心思想是:当缓存空间不足时,淘汰掉最近最少使用的数据块(Page)。它通常用一个链表来实现,链表头部是最近访问的 Page,链表尾部是最久未访问的 Page。 然而,在数据库系统中直接…...
云原生--核心组件-容器篇-7-Docker私有镜像仓库--Harbor
1、Harbor的定义与核心作用 定义: Harbor是由VMware开源的企业级容器镜像仓库系统,后捐赠给 CNCF (Cloud Native Computing Foundation)。它基于Docker Registry扩展了企业级功能,用于存储、分发和管理容器镜像(如Docker、OCI标准…...
TypeScript 实用类型深度解析:Partial、Pick、Record 的妙用
需求背景:在后台系统的用户管理模块中,我们常遇到这样的场景:修改用户资料时只需要传部分字段,展示用户列表时要隐藏敏感信息,快速查找用户需要ID索引等等,这些业务需求都可以通过 TypeScript 的实用类型优…...
【Pandas】pandas DataFrame rmod
Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象(如 DataFrame、Series 或标量)的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…...
如何搭建spark yarn 模式的集群集群
以下是搭建Spark YARN模式集群的一般步骤: 准备工作 - 确保集群中各节点安装了Java环境,并配置好 JAVA_HOME 环境变量。 - 各节点间能通过SSH免密登录。 - 安装并配置好Hadoop集群,YARN作为Hadoop的资源管理器,Spark YARN模式需要…...
云原生--核心组件-容器篇-6-Docker核心之-镜像仓库(公共仓库,私有仓库,第三方仓库)
1、Docker仓库的定义与核心作用 定义: Docker仓库(Docker Registry)是用于存储、分发和管理Docker镜像的集中式存储库。它类似于代码仓库,但专门用于容器镜像的版本控制和共享。它允许开发人员和IT团队高效地管理、部署和分享容器…...
mysql8.0版本部署+日志清理+rsync备份策略
mysql安装:https://blog.csdn.net/qq_39399966/article/details/120205461 系统:centos7.9 数据库版本:mysql8.0.28 1.卸载旧的mysql,保证环境纯净 rpm -qa | grep mariadb mariadb-5.... rpm -e --nodeps 软件 rpm -e --nodeps mariadb-5.…...
搭建spark yarn 模式的集群集群
一.引言 在大数据处理领域,Apache Spark 是一个强大的分布式计算框架,而 YARN(Yet Another Resource Negotiator)是 Hadoop 的资源管理系统。将 Spark 运行在 YARN 模式下,可以充分利用 YARN 强大的资源管理和调度能力…...
在uni-app中使用Painter生成小程序海报
在uni-app中使用Painter生成小程序海报 安装Painter 从GitHub下载Painter组件:https://github.com/Kujiale-Mobile/Painter 将painter文件夹复制到uni-app项目的components目录下 配置页面 在需要使用海报的页面的pages.json中配置 {"path": "pag…...
Uni-app网络请求AES加密解密实现
Uni-app 网络请求封装与 AES 加密解密实现 下面我将为你提供一个完整的 Uni-app 网络请求封装方案,包含 POST 请求的统一处理、请求参数和响应数据的 AES 加密解密。 1. 创建加密解密工具类 首先创建一个 crypto.js 文件用于处理 AES 加密解密: // u…...
uniapp实现统一添加后端请求Header方法
uniapp把请求写完了,发现需要给接口请求添加头部,每个接口去添加又很麻烦,uniapp可以统一添加,并且还能给某些接口设置不添加头部。 一般用于添加token登录验证信息。 在 main.js 文件中配置。 代码如下: // 在…...
uniapp打包apk如何实现版本更新
我们做的比较简单,在后端设置版本号,并在uniapp的config.js中定义版本号,每次跟后端的进行对比,不一致的话就更新。 一、下载apk 主要代码(下载安装包,并进行安装,一般得手动同意安装…...
【Java开发日记】OpenFeign 的 9 个坑
目录 坑一:用对Http Client 1.1 feign中http client 1.2 ribbon中的Http Client 坑二:全局超时时间 坑三:单服务设置超时时间 坑四:熔断超时时间 4.1 使用feign超时 4.2 使用ribbon超时 4.3 使用自定义Options 坑五&…...
RocketMQ 存储核心:深入解析 CommitLog 设计原理
一、引言 在分布式消息队列系统中,消息存储的可靠性和高吞吐能力是衡量系统优劣的核心指标。Apache RocketMQ 作为一款高性能、高可用的分布式消息中间件,其独特的 CommitLog 存储机制在消息持久化过程中扮演了关键角色。本文将深入剖析 CommitLog 的设…...
【C++ Qt】快速上手 显⽰类控件(Label、LCDNumber、ProcessBar、CalendarWidget)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本文围绕Qt中常用的显示类控件展开,重点讲解了 QLabel(文本/图片显示)、QLCDNumber(数字显示࿰…...
Docker和K8s面试题
1.Docker底层依托于linux怎么实现资源隔离的? 基于Namespace的视图隔离:Docker利用Linux命名空间(Namespace)来实现不同容器之间的隔离。每个容器都运行在自己的一组命名空间中、包括PID(进程)、网络、挂载…...