当前位置: 首页 > news >正文

QCustomPlot中自定义QCPAbstractPlottable绘图元素

QCPAbstractPlottable 是 QCustomPlot 中所有可绘制图形(如曲线、柱状图等)的基类。要创建自定义的绘图元素,通常需要继承这个类并实现其纯虚函数。

基本步骤

  1. 继承 QCPAbstractPlottable

  2. 实现必要的纯虚函数

  3. 添加自定义属性和方法

  4. 注册到 QCustomPlot 系统

完整实现示例

下面是一个自定义波形图元素的实现示例:

头文件 (customwaveform.h)

cpp

#include <QObject>
#include "qcustomplot.h"class CustomWaveform : public QCPAbstractPlottable
{Q_OBJECT
public:explicit CustomWaveform(QCPAxis *keyAxis, QCPAxis *valueAxis);~CustomWaveform();// 必须实现的纯虚函数virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const override;// 自定义数据接口void setData(const QVector<double> &keys, const QVector<double> &values);void setWaveformColor(const QColor &color);void setFillGradient(const QLinearGradient &gradient);// 获取范围virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const override;virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const override;protected:// 必须实现的纯虚函数virtual void draw(QCPPainter *painter) override;virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const override;// 自定义属性QVector<double> mKeyData;QVector<double> mValueData;QColor mWaveformColor;QLinearGradient mFillGradient;double mLineWidth;// 辅助方法QPainterPath getWaveformPath() const;
};

实现文件 (customwaveform.cpp)

cpp

#include "customwaveform.h"CustomWaveform::CustomWaveform(QCPAxis *keyAxis, QCPAxis *valueAxis) :QCPAbstractPlottable(keyAxis, valueAxis),mWaveformColor(Qt::blue),mLineWidth(1.5)
{// 初始化填充渐变mFillGradient.setColorAt(0, QColor(0, 0, 255, 50));mFillGradient.setColorAt(1, QColor(0, 0, 255, 0));mFillGradient.setStart(0, 0);mFillGradient.setFinalStop(0, 1);// 设置可选中setSelectable(true);
}CustomWaveform::~CustomWaveform()
{
}double CustomWaveform::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
{if (onlySelectable && !mSelectable)return -1;if (mKeyData.isEmpty() || mValueData.isEmpty())return -1;// 简单实现:检查是否点击了波形线附近const double maxDistSqr = qPow(mParentPlot->selectionTolerance()*0.5, 2);for (int i=1; i<mKeyData.size(); ++i) {QPointF p1(coordsToPixels(mKeyData[i-1], mValueData[i-1]));QPointF p2(coordsToPixels(mKeyData[i], mValueData[i]));double distToLineSqr = QCPVector2D(pos).distanceSquaredToLine(p1, p2);if (distToLineSqr < maxDistSqr) {if (details)details->setValue(i); // 返回数据点索引return qSqrt(distToLineSqr);}}return -1;
}void CustomWaveform::setData(const QVector<double> &keys, const QVector<double> &values)
{if (keys.size() != values.size()) {qDebug() << "Key and value arrays must have equal size";return;}mKeyData = keys;mValueData = values;
}void CustomWaveform::setWaveformColor(const QColor &color)
{mWaveformColor = color;
}void CustomWaveform::setFillGradient(const QLinearGradient &gradient)
{mFillGradient = gradient;
}QCPRange CustomWaveform::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const
{return QCPAbstractPlottable::getKeyRange(foundRange, inSignDomain);
}QCPRange CustomWaveform::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
{return QCPAbstractPlottable::getValueRange(foundRange, inSignDomain, inKeyRange);
}void CustomWaveform::draw(QCPPainter *painter)
{if (mKeyData.isEmpty() || mValueData.isEmpty())return;// 应用默认抗锯齿设置applyDefaultAntialiasingHint(painter);// 获取波形路径QPainterPath path = getWaveformPath();// 绘制填充区域painter->save();painter->setPen(Qt::NoPen);painter->setBrush(mFillGradient);// 创建闭合路径用于填充QPainterPath fillPath = path;fillPath.lineTo(coordsToPixels(mKeyData.last(), 0));fillPath.lineTo(coordsToPixels(mKeyData.first(), 0));fillPath.closeSubpath();painter->drawPath(fillPath);painter->restore();// 绘制波形线painter->setPen(QPen(mWaveformColor, mLineWidth));painter->setBrush(Qt::NoBrush);painter->drawPath(path);// 如果被选中,绘制选中效果if (mSelected) {painter->setPen(QPen(mWaveformColor.lighter(150), mLineWidth*1.5));painter->drawPath(path);}
}void CustomWaveform::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
{// 绘制图例图标painter->setPen(QPen(mWaveformColor, mLineWidth));painter->drawLine(QLineF(rect.left(), rect.center().y(), rect.right(), rect.center().y()));// 绘制渐变填充示例if (mFillGradient != QLinearGradient()) {painter->save();painter->setPen(Qt::NoPen);QLinearGradient legendGrad = mFillGradient;legendGrad.setStart(rect.topLeft());legendGrad.setFinalStop(rect.bottomLeft());painter->setBrush(legendGrad);painter->drawRect(rect.adjusted(0, rect.height()*0.3, 0, -rect.height()*0.3));painter->restore();}
}QPainterPath CustomWaveform::getWaveformPath() const
{QPainterPath path;if (mKeyData.isEmpty() || mValueData.isEmpty())return path;path.moveTo(coordsToPixels(mKeyData.first(), mValueData.first()));for (int i=1; i<mKeyData.size(); ++i) {path.lineTo(coordsToPixels(mKeyData[i], mValueData[i]));}return path;
}

使用自定义的绘图元素

cpp

// 创建自定义波形图
CustomWaveform *waveform = new CustomWaveform(customPlot->xAxis, customPlot->yAxis);// 设置数据
QVector<double> x(500), y(500);
for (int i=0; i<500; ++i) {x[i] = i/50.0; // 0..10y[i] = qSin(x[i]) + qrand()/(double)RAND_MAX*0.5; // 带噪声的正弦波
}
waveform->setData(x, y);// 设置样式
waveform->setWaveformColor(QColor(80, 120, 200));
QLinearGradient gradient;
gradient.setColorAt(0, QColor(80, 120, 200, 100));
gradient.setColorAt(1, QColor(80, 120, 200, 0));
waveform->setFillGradient(gradient);// 添加到图表
customPlot->addPlottable(waveform);// 设置坐标轴范围
customPlot->rescaleAxes();
customPlot->replot();

高级自定义功能

1. 添加自定义交互

cpp

// 在CustomWaveform类中添加
void CustomWaveform::mousePressEvent(QMouseEvent *event, const QVariant &details)
{if (event->button() == Qt::LeftButton && mSelectable) {if (details.isValid() && details.canConvert<int>()) {int dataIndex = details.toInt();qDebug() << "Clicked on data point:" << dataIndex << "Key:" << mKeyData[dataIndex] << "Value:" << mValueData[dataIndex];}}QCPAbstractPlottable::mousePressEvent(event, details);
}

2. 实现数据点编辑

cpp

// 添加数据点编辑功能
void CustomWaveform::setPointEditable(bool editable)
{setSelectable(editable);if (editable) {setInteraction(QCP::iSelectPlottables);} else {setInteraction(QCP::iNone);}
}// 重写mouseMoveEvent实现拖动数据点
void CustomWaveform::mouseMoveEvent(QMouseEvent *event, const QVariant &details)
{if (mSelected && details.isValid() && details.canConvert<int>()) {int pointIndex = details.toInt();double newKey = keyAxis()->pixelToCoord(event->pos().x());double newValue = valueAxis()->pixelToCoord(event->pos().y());mKeyData[pointIndex] = newKey;mValueData[pointIndex] = newValue;emit dataChanged(); // 自定义信号}
}

3. 添加动画效果

cpp

// 添加动画方法
void CustomWaveform::animateTo(const QVector<double> &newValues, int durationMs)
{if (newValues.size() != mValueData.size())return;QPropertyAnimation *anim = new QPropertyAnimation(this, "animationProgress");anim->setDuration(durationMs);anim->setStartValue(0.0);anim->setEndValue(1.0);mAnimationStartValues = mValueData;mAnimationEndValues = newValues;connect(anim, &QPropertyAnimation::valueChanged, [=](){this->updateAnimation();});connect(anim, &QPropertyAnimation::finished, [=](){mValueData = mAnimationEndValues;anim->deleteLater();});anim->start();
}// 动画更新
void CustomWaveform::updateAnimation()
{double progress = property("animationProgress").toDouble();for (int i=0; i<mValueData.size(); ++i) {mValueData[i] = mAnimationStartValues[i] + (mAnimationEndValues[i] - mAnimationStartValues[i]) * progress;}mParentPlot->replot(QCustomPlot::rpQueuedReplot);
}

性能优化技巧

  1. 数据分块处理

    cpp

    void CustomWaveform::draw(QCPPainter *painter)
    {const int chunkSize = 1000; // 每块处理1000个点for (int i=0; i<mKeyData.size(); i+=chunkSize) {int end = qMin(i+chunkSize, mKeyData.size());// 绘制当前块...}
    }
  2. 使用OpenGL加速

    cpp

    // 在构造函数中
    if (QOpenGLContext::currentContext()) {mUseOpenGl = true;mOpenGlBuffer.initializeGL();
    }
  3. 实现细节层次(LOD)

    cpp

    void CustomWaveform::draw(QCPPainter *painter)
    {// 根据视图范围决定绘制细节double pixelsPerPoint = (keyAxis()->axisRect()->width() / keyAxis()->range().size()) * (mKeyData.size() > 1 ? 1.0/(mKeyData.size()-1) : 1.0);if (pixelsPerPoint < 0.5) {// 低细节模式drawLowDetail(painter);} else {// 高细节模式drawHighDetail(painter);}
    }

通过继承 QCPAbstractPlottable,您可以创建完全自定义的绘图元素,实现各种复杂的数据可视化效果。这种方法的优势在于可以完全控制绘图过程,同时还能与 QCustomPlot 的其他功能(如坐标轴、图例、交互等)无缝集成。

相关文章:

QCustomPlot中自定义QCPAbstractPlottable绘图元素

QCPAbstractPlottable 是 QCustomPlot 中所有可绘制图形(如曲线、柱状图等)的基类。要创建自定义的绘图元素&#xff0c;通常需要继承这个类并实现其纯虚函数。 基本步骤 继承 QCPAbstractPlottable 实现必要的纯虚函数 添加自定义属性和方法 注册到 QCustomPlot 系统 完…...

【Bluedroid】蓝牙 HID 设备信息加载与注册机制及配置缓存系统源码解析

本篇解析Android蓝牙子系统加载配对HID设备的核心流程&#xff0c;通过btif_storage_load_bonded_hid_info实现从NVRAM读取设备属性、验证绑定状态、构造描述符并注册到BTA_HH模块。重点剖析基于ConfigCache的三层存储架构&#xff08;全局配置/持久设备/临时设备&#xff09;&…...

【计算机视觉】CV实战项目 - PCC-Net 人群计数

PCC-Net 人群计数项目 项目特点项目运行方式与步骤1. 环境准备2. 数据准备3. 模型训练4. 实验结果 常见问题及解决方法 PCC-Net&#xff08;Perspective Crowd Counting via Spatial Convolutional Network&#xff09;是一个用于人群计数的深度学习项目&#xff0c;旨在通过空…...

Towards Transferable Targeted 3D Adversarial Attack in the Physical World--阅读笔记

目录 简介&#xff1a; 背景&#xff1a; 挑战&#xff1a; 目的&#xff1a; 技术细节&#xff1a; 贡献&#xff1a; ​​1. NeRF的核心作用&#xff1a;3D重建与参数化表示​​ ​​2. 对抗优化的创新&#xff1a;NeRF参数空间的双优化​​ ​​2.1 传统方法的局限…...

​opencv图像库编程

一、下载安装 opencv 1.1 下载安装包 1.2 解压缩 unzip opencv-3.4.11.zip 解压缩以后主目录文件夹如下&#xff1a; 1.3 进入到解压后的文件夹中 cd opencv-3.4.11 二、使用 cmake安装opencv 2.1 进入 root 用户&#xff0c;并更新一下 sudo su sudo apt-get update …...

星拍相机APP:时尚与科技的完美融合,打造你的专属美

在数字时代&#xff0c;手机相机不仅是记录生活的工具&#xff0c;更是表达个性和创意的平台。今天&#xff0c;我们要介绍的 星拍相机APP&#xff0c;就是这样一款匠心制作的手机相机应用。它融合了时尚与科技&#xff0c;提供了多样化的魔法美颜功能&#xff0c;让每一次拍摄…...

puzzle(0531)脑力航迹

目录 脑力航迹 规则 解法 简单模式 中等模式 困难模式 专家模式 脑力航迹 规则 2条航迹会产生一个相对航迹&#xff1a; 根据相对航迹和其中一个航迹推导另外一个航迹。 解法 没有任何需要推理的地方&#xff0c;就是纯粹的2个矢量相加。 简单模式 中等模式 困难模…...

【英语语法】词法---形容词

目录 形容词1. 形容词的核心功能2. 形容词的位置(1) 前置定语&#xff08;最常见&#xff09;(2) 后置定语&#xff08;特殊情况&#xff09;(3) 表语位置&#xff08;系动词后&#xff09; 3. 形容词的比较级与最高级(1) 规则变化(2) 不规则变化(3) 用法对比 4. 多个形容词修饰…...

理解 React 的 useEffect

文章目录 React 的 useEffect一、什么是副作用&#xff08;Side Effects&#xff09;&#xff1f;二、useEffect 的基本用法三、依赖数组的三种情况1. 无依赖数组&#xff08;每次渲染后都执行, 不推荐&#xff09;2. 空依赖数组&#xff08;仅在挂载时执行一次&#xff09;3. …...

2.1 基于委托的异步编程方法

基于委托的异步编程模型是 .NET 早期版本中实现异步操作的一种方式,主要通过 BeginInvoke 和 EndInvoke 方法来实现。这种基于委托的异步模式已被 Task 和 async/await 模式取代,但在维护旧代码时仍可能遇到这种模式。 委托的方法中:Invoke用于同步调用; 而BeginInvoke与E…...

对于在线教育或知识付费类网站视频处理方案

一、视频格式&#xff1a; 1. 推荐格式&#xff1a;HLS&#xff08;HTTP Live Streaming&#xff09; 优势‌&#xff1a; ‌自适应码率‌&#xff1a;根据用户网络状况自动切换清晰度&#xff0c;避免卡顿。‌广泛兼容性‌&#xff1a;iOS/macOS 原生支持&#xff0c;Android…...

Gen - CDPT举例说明:动态上下文前缀(输入先和标签结合,输出结果会更贴近标签内容)

Gen - CDPT举例说明:动态上下文前缀(输入先和标签结合,输出结果会更贴近标签内容) 目录 Gen - CDPT举例说明:动态上下文前缀(输入先和标签结合,输出结果会更贴近标签内容)输入文本示例Gen - CDPT模型处理过程示例什么是:提示次优动态前缀提示方法生成与这条评论上下文…...

UCSC CTF 2025|MISC

1、USB flag{ebdfea9b-3469-41c7-9070-d7833ecc6102} 2、three part1是图片隐水印 part1&#xff1a;8f02d3e7 part2是2进制变换 -ce89-4d6b-830e- Part3先从pass.pcapng得到密码字典 解压缩密码&#xff1a;thinkbell 3个部分合并得到flag{8f02d3e7-ce89-4d6b-830e-5d0cb5…...

FTP客户端实现(文件传输)

文章目录 &#x1f9f1; 一、FTP 基础架构回顾&#x1f680; 二、FTP 客户端的核心结构&#x1f517; 三、连接与登录过程&#x1f4cc; 1. ftp_create()&#x1f4cc; 2. ftp_connect()&#x1f4cc; 3. ftp_login() &#x1f4c1; 四、上传文件实现&#xff08;ftp_upload_fi…...

状态管理最佳实践:Bloc架构实践

状态管理最佳实践&#xff1a;Bloc架构实践 引言 Bloc (Business Logic Component) 是Flutter中一种强大的状态管理解决方案&#xff0c;它基于响应式编程思想&#xff0c;通过分离业务逻辑和UI表现层来实现清晰的代码架构。本文将深入探讨Bloc的核心概念、实现原理和最佳实践…...

嵌入式人工智能应用-第三章 opencv操作 5 二值化、图像缩放

嵌入式人工智能应用 嵌入式人工智能应用-第三章 opencv操作 5 二值化 嵌入式人工智能应用1 二值化1.1 概念介绍1.2 函数介绍1.2 基本应用1.3 参考案例 2 图像缩放2.1 基本概念2.2 函数介绍2.3 基本参考代码2.4 pyrUp 和 pyrDown 函数2.5 函数介绍2.6 参考代码2.7 总结 1 二值化…...

[OS_7] 访问操作系统对象 | offset | FHS | Handle

实验代码可以看去年暑假的这篇文章&#xff1a;【Linux】进程间通信&#xff1a;详解 VSCode使用 | 匿名管道 我们已经知道&#xff0c;进程从 execve 后的初始状态开始&#xff0c;可以通过 mmap 改变自己的地址空间&#xff0c;通过 fork 创建新的进程&#xff0c;再通过 exe…...

【Vulkan 入门系列】创建帧缓冲、命令池、命令缓存,和获取图片(六)

这一节主要介绍创建帧缓冲&#xff08;Framebuffer&#xff09;&#xff0c;创建命令池&#xff0c;创建命令缓存&#xff0c;和从文件加载 PNG 图像数据&#xff0c;解码为 RGBA 格式&#xff0c;并将像素数据暂存到 Vulkan 的 暂存缓冲区中。 一、创建帧缓冲 createFramebu…...

Linux 进程控制(自用)

非阻塞调用waitpid 这样父进程就不会阻塞&#xff0c;此时循环使用我们可以让父进程执行其他任务而不是阻塞等待 进程程序替换 进程PCB加载到内存中的代码和数据 替换就是完全替换当前进程的代码段、数据段、堆和栈&#xff0c;保存当前的PCB 代码指的是二进制代码不是源码&a…...

FreeSWITCH 简单图形化界面41 - 批量SIP视频呼叫测试

FreeSWITCH 简单图形化界面41 - 批量视频测试 0、界面预览00、安装测试工具1、注册分机2、设置接听选项2.1 上传媒体文件2.2 设置接听设置 3、呼叫测试 0、界面预览 http://myfs.f3322.net:8020/ 用户名&#xff1a;admin&#xff0c;密码&#xff1a;admin FreeSWITCH界面安…...

通过爬虫方式实现头条号发布视频(2025年4月)

1、将真实的cookie贴到代码目录中toutiaohao_cookie.txt文件里,修改python代码里的user_agent和video_path, cover_path等变量的值,最后运行python脚本即可; 2、运行之前根据import提示安装一些常见依赖,比如requests等; 3、2025年4月份最新版; 代码如下: import js…...

《AI大模型应知应会100篇》第28篇:大模型在文本创作中的应用技巧

第28篇&#xff1a;大模型在文本创作中的应用技巧 &#x1f9e0; 摘要 在内容为王的时代&#xff0c;AI大模型正在重塑文本创作的每一个环节。从创意构思到风格润色&#xff0c;从论文报告到小说脚本&#xff0c;AI不仅是创作者的助手&#xff0c;更是灵感的激发器。本文将带你…...

字节跳动发布UI-TARS-1.5,入门AI就来近屿智能

近日&#xff0c;字节跳动在 Hugging Face 平台正式开源了其最新多模态代理模型——UI-TARS-1.5。作为 UI-TARS 系列的革新之作&#xff0c;该模型以视觉语言模型为基础&#xff0c;突破性实现跨平台 GUI 自动化交互&#xff0c;为自动化与智能交互领域注入了强劲动能。无论是开…...

大数据学习栈记——MapReduce技术

本文介绍hadoop中的MapReduce技术的应用&#xff0c;使用java API。操作系统&#xff1a;Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一个分布式运算程序的编程框架&#xff0c;核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序…...

GO语言入门:常用数学函数2

14.6 大型数值 math/big 包中公开了一些实用 API&#xff0c;用于表示大型整数值和浮点数值。当基础类型无法容纳要使用的数值时&#xff0c;应改用 big 包中提供的新类型。例如 Int、Float 等。 14.6.1 大型整数值之间的运算 若希望让下面两个整数值完成加、减法运算&#…...

Django 使用教程

Django 使用教程 Django 是一个高级的 Python Web 框架&#xff0c;采用了 MTV&#xff08;Model-Template-View&#xff09;设计模式&#xff0c;旨在帮助开发者快速构建高效、可维护的 Web 应用。它有着非常丰富的功能&#xff0c;包括 ORM、用户认证、表单处理、管理后台等…...

deepseek + kimi制作PPT

目录 一、kimi简介二、deepseek生成内容三、生成PPT四、编辑PPT 一、kimi简介 kimi是一款只能ppt生成器&#xff0c;擅长将文本内容生成PPT。 在这里&#xff0c;​​DeepSeek 负责内容生成与逻辑梳理​​&#xff0c;​​Kimi 优化表达与提供设计建议​​。 二、deepseek生…...

C++学习:六个月从基础到就业——内存管理:RAII原则

C学习&#xff1a;六个月从基础到就业——内存管理&#xff1a;RAII原则 本文是我C学习之旅系列的第十九篇技术文章&#xff0c;也是第二阶段"C进阶特性"的第四篇&#xff0c;主要介绍C中的RAII原则及其在资源管理中的应用。查看完整系列目录了解更多内容。 引言 在…...

量子计算与经典计算融合:开启计算新时代

一、引言 随着科技的飞速发展&#xff0c;计算技术正迎来一场前所未有的变革。量子计算作为前沿技术&#xff0c;以其强大的并行计算能力和对复杂问题的高效处理能力&#xff0c;吸引了全球科技界的关注。然而&#xff0c;量子计算并非要完全取代经典计算&#xff0c;而是与经典…...

RV1126网络环境TFTPNFS搭建(二)

二、RV1126 开发板TFTP环境搭建 2.1、Ubuntu下安装和配置 xinetd 执行以下指令&#xff0c;安装 xinetd sudo apt-get install xinetd 执行以下指令创建一个 xinetd.conf 文件 sudo vi /etc/xinetd.conf 修改 xinetd.conf 文件内容如下&#xff1a; # Simple configurat…...

计算机视觉7——齐次坐标与相机内外参

一、透视投影 透视投影&#xff08;Perspective Projection&#xff09;是计算机视觉和图形学中描述三维物体在二维平面成像的基础模型&#xff0c;其核心思想是模拟人类视觉系统的成像原理——中心投影。具体而言&#xff0c;三维空间中的点通过一个固定的投影中心&#xff0…...

学习笔记—C++—string(一)

目录 string 为什么学习string的类 string类的常用接口 string类对象的常见构造 string类对象的访问及遍历操作 operator[] 迭代器 范围for auto 迭代器&#xff08;二&#xff09; string类对象的容量操作 size,length,max_size,capacity,clear基本用法 reserve 提…...

Linux命令-Shell编程

Shell是一个命令行解释器&#xff0c;它接收应用程序/用户命令&#xff0c;然后调用操作系统内核。 写一个hello.sh脚本&#xff1a; 1.mkdir scripts 2.cd scripts 3.touch hello.sh 4.vim hello.sh #!/bin/bash echo "hello,world" 5.bash hello.sh&#xff08…...

基于Django的AI客服租车分析系统

基于Django的AI客服租车分析系统 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】AI智能客服与用户交互指导手册 【技术栈】 ①&#xff1a;系统环境&#xff1a;Python 3.8&#xff0c;Django 4.2框架 ②&#xff1a;开发环境&a…...

计算机组成与体系结构:计算机结构的分类(classifications of computer architecture)

目录 Von Neumann Architecture&#xff08;冯诺依曼结构&#xff09; Harvard Architecture&#xff08;哈佛结构&#xff09; Modified Harvard Architecture&#xff08;改进哈佛结构&#xff09; 三种结构对比总结表 &#x1f4a1; 从“内存访问结构”角度分类&#x…...

在阿里云和树莓派上编写一个守护进程程序

目录 一、阿里云邮件守护进程 1. 安装必要库 2. 创建邮件发送脚本 mail_daemon.py 3. 设置后台运行 二、树莓派串口守护进程 1. 启用树莓派串口 2. 安装依赖库 3. 创建串口输出脚本 serial_daemon.py 4. 设置开机自启 5. 使用串口助手接收 一、阿里云邮件守护进程 1.…...

Redis 的几种数据类型

Redis 提供了多种数据类型&#xff0c;以支持不同的应用场景。每种数据类型都有其特定的操作方式&#xff0c;并且在内部实现上也有所优化&#xff0c;能够满足不同的业务需求。以下是 Redis 支持的几种常见数据类型&#xff1a; 1. 字符串&#xff08;String&#xff09; 描…...

Spring之我见 - Spring Boot Starter 自动装配原理

欢迎光临小站&#xff1a;致橡树 Spring Boot Starter 的核心设计理念是 约定优于配置&#xff0c;其核心实现基于 自动配置&#xff08;Auto-Configuration&#xff09; 和 条件化注册&#xff08;Conditional Registration&#xff09;。以下是其生效原理&#xff1a; 约定…...

LeRobot 项目部署运行逻辑(二)—— Mobile Aloha 真机部署

LeRobot 在开源项目中详细说明了部署流程&#xff0c;所以首先看一下开源的内容&#xff0c;然后再逐步拆解 首先&#xff0c;LeRobot 开源的硬件是配全部在 examples 文件夹中 包括了 Stretch 3、Aloha and Aloha 2 stationary、SO-100、LeKiwi、Moss v1 等机器人 恰好实验…...

大模型面经 | 介绍一下CLIP和BLIP

大家好,我是皮先生!! 今天给大家分享一些关于大模型面试常见的面试题,希望对大家的面试有所帮助。 往期回顾: 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题一) 大模型面经 | 春招、秋招算法面试常考八股文附答案(RAG专题二) 大模型面经 | 春招、秋招算法…...

Java发生OOM是否必然导致JVM退出

Java发生OOM是否必然导致JVM退出&#xff1f; 核心结论 不一定。OOM是否导致JVM退出取决于以下因素&#xff1a; OOM发生的区域JVM启动参数配置是否捕获了OOM异常 详细分析 1. 不同内存区域的OOM影响 内存区域错误类型默认是否导致JVM退出可恢复性Java堆OutOfMemoryError…...

Docker Compose 外部网络(`external: true`)与内部网络的区别

Docker Compose 外部网络(external: true)与内部网络的区别 在 Docker Compose 中&#xff0c;external: true 声明的外部网络与普通(内部)网络有重要区别&#xff0c;以下是它们的详细对比&#xff1a; 1. 定义与创建方式 特性外部网络 (external: true)内部网络 (默认)创建…...

【Android】Wallpaper学习

从wallpaper的设置来了解相关内容&#xff1a; 一&#xff0c;静态壁纸 静态壁纸设置的原理是在WallpaperManagerService里监听/data/system/users/0/wallpaper_orig相关文件的变化来触发设置&#xff0c;通过相应的组件程序去进行绘制&#xff0c; 相应的组件如&#xff1a…...

Java基础-第一章、基本数据类型

运算符&#xff1a; 1.算术运算符&#xff1a;加减乘除%等 2.逻辑运算符&#xff1a;与或非等 3.关系运算符&#xff1a;大于、小于... 4.赋值运算符&#xff1a; 这里牵扯运算符的运算先后顺序了。 赋值运算的返回值&#xff1a;就是赋值的变量本身...

《Operating System Concepts》阅读笔记:p748-p748

《Operating System Concepts》学习第 64 天&#xff0c;p748-p748 总结&#xff0c;总计 1 页。 一、技术总结 1.Transmission Control Protocol(TCP) 重点是要自己能画出其过程&#xff0c;这里就不赘述了。 二、英语总结(生词&#xff1a;3) transfer, transport, tran…...

Arduino示例代码讲解:Project 08 - Digital Hourglass 数字沙漏

Arduino示例代码讲解:Project 08 - Digital Hourglass 数字沙漏 Project 08 - Digital Hourglass 数字沙漏程序功能概述功能:硬件要求:输出:代码结构全局变量`setup()` 函数`loop()` 函数计时和点亮LED:读取倾斜开关状态:重置LED和计时器:运行过程注意事项Project 08 - …...

报告总结笔记 | Jeff Dean ETH AI趋势 笔记:AI 的重要趋势:我们是如何走到今天的,我们现在能做什么,以及我们如何塑造 AI 的未来?

报告总结笔记 | Jeff Dean ETH AI趋势 笔记&#xff1a;AI 的重要趋势&#xff1a;我们是如何走到今天的&#xff0c;我们现在能做什么&#xff0c;以及我们如何塑造 AI 的未来&#xff1f; 2025年 4 月 14 日&#xff0c;Google Research 及 Google DeepMind 的首席科学家、A…...

RocketMQ实现基于可靠消息的最终一致性

RocketMQ实现基于可靠消息的最终一致性 文章目录 RocketMQ实现基于可靠消息的最终一致性一、RocketMQ应用场景**应用解耦****流量削峰****数据分发** 二、RocketMQ 基础概念1. 核心组件2. 消费模式3. 消息可靠性 三、消息类型按发送方式分同步发送异步发送单向发送 按使用功能特…...

【题解-Acwing】790. 数的三次方根

题目:790. 数的三次方根 题目描述 给定一个浮点数 n,求它的三次方根。 输入 共一行,包含一个浮点数 n 。 输出 共一行,包含一个浮点数,表示问题的解。 注意,结果保留 6 位小数。 数据范围 −10000 ≤ n ≤ 10000 时空限制 1s / 64MB 输入样例 1000.00输出样…...

一键升级OpenSSH/OpenSSL修复安全漏洞

在服务器安全运维过程中&#xff0c;我们经常面临这样的问题&#xff1a;收到高危漏洞通报&#xff08;如最近的OpenSSH多个CVE漏洞&#xff09;&#xff0c;但Ubuntu系统无法通过apt直接升级到修复版本。这种情况下&#xff0c;传统方法需要手动编译源码&#xff0c;处理依赖关…...