QT开发---图形与图像(补充)
!!!本文所讲内容相关代码已上传博客,感兴趣的同学可以去博主主页下载
坐标映射
在 Qt 的QGraphicsView
框架(QGraphicsView
+ QGraphicsScene
+ QGraphicsItem
)中,坐标映射是核心机制之一。由于存在视图、场景、图元三个层级的坐标系,理解它们之间的映射关系是实现复杂交互(如选中、拖拽、对齐、碰撞检测等)的关键。
坐标映射方法
视图 ↔ 场景 映射(QGraphicsView
)
QGraphicsView
作为场景的 "观察者",负责将场景的逻辑坐标转换为屏幕像素坐标(视图坐标),或反之。
mapToScene(const QPoint &viewPos) → QPointF
将视图坐标系中的点(像素坐标)转换为场景坐标系中的点(逻辑坐标)
参数细节:
viewPos:视图中的点,单位是像素(与QMouseEvent::pos()返回值直接对应)
返回值:场景中的点,类型为QPointF(支持小数,因场景是逻辑坐标)
转换逻辑:
先扣除视图的滚动偏移(horizontalScrollBar()和verticalScrollBar()的当前值)
再应用视图的变换矩阵(transform()),处理缩放、旋转等视图级别的变换
最终得到场景中的逻辑坐标
mapFromScene(const QPointF &scenePos) → QPoint
将场景坐标系中的点转换为视图坐标系中的点(像素坐标)
参数细节:
scenePos:场景中的逻辑点(可含小数)
返回值:视图中的像素点(整数,因屏幕坐标是离散像素)
转换逻辑:
先应用视图变换矩阵的逆矩阵(抵消缩放、旋转等)
再加上视图的滚动偏移
最终得到视图上的像素坐标
mapToScene(const QRect &viewRect) → QRectF
mapFromScene(const QRectF &sceneRect) → QRect
将视图中的矩形区域(像素范围)与场景中的矩形区域(逻辑范围)互相转换
特殊处理:
不仅转换四个顶点,还会考虑区域的整体变换(如旋转视图后,矩形可能变为梯形,
但mapToScene会返回包含原区域的最小矩形)
常用于 "视图可见区域" 与 "场景可见区域" 的映射
(如view->mapToScene(view->viewport()->rect())可获取当前视图显示的场景范围)
图元 ↔ 场景 映射(QGraphicsItem
)
QGraphicsItem
作为场景中的元素,其坐标映射需要考虑自身变换(旋转、缩放)、父图元变换和场景位置。
mapToScene(const QPointF &itemPos) → QPointF
将图元自身坐标系中的点,转换为场景坐标系中的点
参数:
itemPos:图元局部坐标(相对于自身左上角(0,0))
返回值:场景中的绝对逻辑坐标
转换逻辑(核心!):
先应用图元自身的变换矩阵(transform()),处理旋转、缩放、倾斜等
加上图元自身的位置(pos()),得到相对于父图元的坐标
若存在父图元,重复步骤 1-2(递归应用父图元的变换和位置)
最终得到相对于场景的坐标
易错点:
图元的pos()是其变换原点在父图元中的位置,而非左上角(默认变换原点是左上角,但可通过setTransformOriginPoint修改)
若修改了变换原点(如setTransformOriginPoint(50,50))
旋转 / 缩放会围绕该点进行mapToScene会自动计算偏移
mapFromScene(const QPointF &scenePos) → QPointF
将场景坐标系中的点,转换为图元自身坐标系中的点
转换逻辑:与mapToScene完全相反,是逆过程:
从场景坐标中减去所有父图元的位置和变换(递归)
应用当前图元变换矩阵的逆矩阵(抵消自身旋转、缩放)
最终得到相对于图元自身的坐标
图元 ↔ 图元 映射(QGraphicsItem
)
直接在两个图元的局部坐标系之间转换,本质是通过场景坐标系中转,但 Qt 封装了简化方法。
mapToItem(QGraphicsItem *other, const QPointF &itemPos) → QPointF
将当前图元的局部坐标,直接转换为目标图元other的局部坐标
内部逻辑:等价于other->mapFromScene(this->mapToScene(itemPos))
即当前图元局部坐标 → 场景坐标 → 目标图元局部坐标
mapFromItem(QGraphicsItem *other, const QPointF &otherPos) → QPointF
将目标图元other的局部坐标,转换为当前图元的局部坐标
内部逻辑:等价于this->mapFromScene(other->mapToScene(otherPos))
注意事项:
-
变换矩阵的优先级:
- 图元的
transform()
(旋转、缩放等)优先于pos()
(位置)应用; - 父图元的变换会影响所有子图元(子图元的
mapToScene
会自动叠加父变换)。
- 图元的
-
空指针与无效目标:
- 调用
mapToItem(other, ...)
时,若other
为nullptr
或与当前图元不在同一场景,会返回QPointF(0,0)
(无效结果); - 务必先通过
scene()
判断两个图元是否属于同一场景。
- 调用
-
浮点精度问题:
- 场景坐标和图元局部坐标支持浮点(
QPointF
),视图坐标是整数(QPoint
); - 频繁转换可能累积精度误差,高精度场景需手动校准(如四舍五入)。
- 场景坐标和图元局部坐标支持浮点(
-
QGraphicsView::viewport()
的坐标:- 视图的坐标是相对于
QGraphicsView
控件本身,而viewport()
是实际显示场景的部件(可能有边框); - 若需处理
viewport()
的坐标(如QWheelEvent
的位置),需先用viewport()->mapTo(this, event->pos())
转换为视图坐标,再调用mapToScene
。
- 视图的坐标是相对于
转换总结 :
视图点 → 场景点 view->mapToScene(viewPos)
场景点 → 视图点 view->mapFromScene(scenePos)
图元点 → 场景点 item->mapToScene(itemPos)
场景点 → 图元点 item->mapFromScene(scenePos)
图元 A 点 → 图元 B 点 A->mapToItem(B, aPos)
图元 A 点 → 视图点 view->mapFromScene(A->mapToScene(aPos))
视图点 → 图元 A 点 A->mapFromScene(view->mapToScene(viewPos))
属性动画
在 Qt 中,属性动画(QPropertyAnimation
)是QAbstractAnimation
的子类,用于对 QObject 的属性进行动画效果处理,比如改变控件的位置、大小、透明度等。它基于 Qt 的元对象系统,能够方便地实现各种动态效果,为用户界面增添交互性和美观性。
QPropertyAnimation interpolates over Qt properties. As property values are stored in QVariants, the class inherits QVariantAnimation, and supports animation of the same meta types as its super class.
A class declaring properties must be a QObject. To make it possible to animate a property, it must provide a setter (so that QPropertyAnimation can set the property's value). Note that this makes it possible to animate many of Qt's widgets.QPropertyAnimation对Qt属性进行插值。由于属性值存储在QVariants中,该类继承QVariantAnimation,并支持与其超类相同元类型的动画。
声明属性的类必须是QObject。为了让属性有动画效果,它必须提供一个setter(以便QPropertyAnimation可以设置属性的值)。请注意,这使得Qt的许多部件可以产生动画效果。
基本原理
属性动画的核心原理是在指定的时间段内,以一定的插值方式,改变对象的某个属性值。Qt 的元对象系统使得它能够识别和操作 QObject 派生类中用Q_PROPERTY
宏声明的属性。动画会根据设定的起始值、结束值、持续时间等参数,自动计算每一帧的属性值并应用到对象上,从而产生连续变化的动画效果。
QPropertyAnimation类
:
QPropertyAnimation
用于对 QObject 的单个属性(如位置、大小、透明度等)进行动画控制,是最基础的动画类。
常用方法:
QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = nullptr)
QPropertyAnimation构造函数
- 参数:
- target:动画作用的目标对象(必须是 QObject 派生类,如 QPushButton、QWidget)
- propertyName:要动画的属性名(需用 Q_PROPERTY 声明,如 "pos"、"size"、"windowOpacity")
- parent:父对象(用于内存管理)。
- eg:new QPropertyAnimation(button, "pos", this) 表示对 button 的 pos 属性(位置)创建动画void setStartValue(const QVariant &value)
设置动画的起始属性值,若不设置则默认使用动画启动时的当前属性值
- 注意:值的类型必须与目标属性匹配
(如 pos 属性对应 QPoint 或 QPointF,windowOpacity 对应 double)void setEndValue(const QVariant &value)
设置动画的结束属性值(必填,否则动画无效果)void setKeyValueAt(qreal step, const QVariant &value)
定义关键帧,实现多段式动画(如先快后慢、往返运动)
- 参数:
- step:进度点(0.0 表示开始,1.0 表示结束,如 0.5 表示中间点)
- value:该进度点的属性值
- eg:
animation->setKeyValueAt(0.3, 100); //30%进度时达到100
animation->setKeyValueAt(0.7, 50); //70%进度时回落到50void setDuration(int msecs)
设置动画持续时间(单位:毫秒,默认 250ms)void setEasingCurve(const QEasingCurve &curve)
设置动画的插值曲线,控制属性值变化的节奏(如加速、减速、弹跳等)
- 常用曲线:
- QEasingCurve::Linear:匀速变化
- QEasingCurve::InQuad:先慢后快(加速)
- QEasingCurve::OutQuad:先快后慢(减速)
- QEasingCurve::InOutQuad:先加速后减速(平滑过渡)
- QEasingCurve::Bounce:弹跳效果(常用于结束时)void setLoopCount(int count)
设置动画循环次数(默认 1 次)
- 特殊值:-1 表示无限循环(需手动调用 stop() 终止)void start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped)
启动动画,若动画已在运行则重启
- 参数:
- policy:动画结束后的删除策略(KeepWhenStopped 保留对象,DeleteWhenStopped 自动删除)
- eg:animation->start(QAbstractAnimation::DeleteWhenStopped)
(适合临时动画,自动释放内存)void stop() / void pause() / void resume()
- stop():停止动画,属性值保留当前状态
- pause():暂停动画,后续可通过 resume() 恢复
- resume():从暂停处继续运行动画
常用信号:
void valueChanged(const QVariant &value)
动画运行中,属性值每次更新时触发(可获取当前帧的属性值)
void finished()
动画完成(包括正常结束、循环结束)时触发
void started()
动画开始运行时触发
void stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
动画状态变化时触发(如从 Stopped → Running,Running → Paused 等)
QParallelAnimationGroup类
:
QParallelAnimationGroup
用于同时运行多个动画(可以是不同对象的不同属性),所有动画同时开始,整体结束时机以最后完成的动画为准。
常用方法:
QParallelAnimationGroup(QObject *parent = nullptr)
构造函数 构造一个空的并行动画组,parent 用于内存管理
eg:QParallelAnimationGroup *group = new QParallelAnimationGroup; int addAnimation(QAbstractAnimation *animation)
将动画添加到组中,启动组时所有动画同时开始
- 参数:animation 是要添加的动画(可以是 QPropertyAnimation 或其他动画组)
- 返回值:动画在组中的索引(从 0 开始)
- 注意:添加后动画的父对象会自动设为组(除非已指定父对象)
- eg:
group->addAnimation(posAnim); //添加位置动画
group->addAnimation(sizeAnim); //添加大小动画void removeAnimation(QAbstractAnimation *animation)
从组中移除指定动画(不会删除动画对象,需手动管理其生命周期)
- 注意:若动画正在运行,移除后会被停止QAbstractAnimation *animationAt(int index) const
获取组中索引为 index 的动画(用于单独控制组内某个动画)
- eg:QPropertyAnimation *anim = dynamic_cast<QPropertyAnimation*>(group->animationAt(0))int animationCount() const
返回组中动画的数量(用于遍历或判断是否为空)void clear()
移除组中所有动画(但不删除动画对象),常用于重置动画组void setLoopCount(int count)
设置整个组的循环次数(所有动画同步循环,循环时重新开始所有动画)
- eg:group->setLoopCount(2) 表示两组动画同时执行 2 次void start(...) / void stop()
启动 / 停止组中所有动画(start 的参数与 QPropertyAnimation 相同)
- 特点:启动时所有动画同时开始;停止时所有动画立即中断
常用信号:
void finished()
所有动画都完成时触发(以最后结束的动画为准)
void started()
开始运行时触发(所有动画开始的时刻)
void stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
状态变化时触发(如开始、暂停、停止)
void animationAdded(QAbstractAnimation *animation, int index)
添加动画时触发
void animationRemoved(QAbstractAnimation *animation, int index)
移除动画时触发
QSequentialAnimationGroup类
:
QSequentialAnimationGroup
用于按顺序逐个运行多个动画,前一个动画完成后,下一个动画才开始。
常用方法:
QSequentialAnimationGroup(QObject *parent = nullptr)
构造函数 构造一个空的顺序动画组int addAnimation(QAbstractAnimation *animation)
将动画添加到组的末尾(按添加顺序执行)
- eg:添加 A、B、C 三个动画,则执行顺序为 A→B→Cvoid insertAnimation(int index, QAbstractAnimation *animation)
- 参数:index 是插入位置(0 表示第一个)
- 功能:在指定位置插入动画,调整执行顺序
- eg:在索引 1 插入动画 D,则原顺序 A→B→C 变为 A→D→B→CQAbstractAnimation *currentAnimation() const
获取当前正在运行的动画(用于实时监控执行状态)
- eg:
if (group->currentAnimation() == animB)
{qDebug() << "正在执行动画B";
}void setLoopCount(int count)
设置整个组的循环次数(所有动画按顺序循环,如 A→B→A→B)void start(...) / void stop()
- start:启动组,按顺序执行第一个动画,前一个动画结束后自动执行下一个
- stop:停止当前动画,后续动画不再执行(状态停留在当前位置)
常用信号:
void finished()
所有动画按顺序执行完成时触发
void started()
开始运行第一个动画时触发
void currentAnimationChanged(QAbstractAnimation *current)
当前运行的动画切换时触发(如下一个动画开始)
void stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
状态变化时触发
void animationAdded(QAbstractAnimation *animation, int index)
添加动画时触发
void animationRemoved(QAbstractAnimation *animation, int index)
移除动画时触发
属性动画总结:
- 基础动画:用
QPropertyAnimation
的setStartValue
、setEndValue
、setDuration
实现简单动画(如按钮移动) - 复杂路径:通过
setKeyValueAt
定义关键帧(如物体先左移再上移) - 节奏控制:用
setEasingCurve
调整动画质感(如弹跳效果用Bounce
曲线) - 同步动画:用
QParallelAnimationGroup::addAnimation
实现多属性同时变化(如移动 + 变色) - 分步动画:用
QSequentialAnimationGroup::addAnimation
实现流程化动画(如先显示再隐藏) - 动态管理:通过
removeAnimation
、insertAnimation
动态调整动画组内容(如根据用户操作增减动画步骤)
QCustomPlot绘图
QCustomPlot 介绍
QCustomPlot
是一个基于 Qt 的开源图表库,支持绘制折线图、散点图、柱状图、饼图等多种图表,且提供了丰富的交互功能(如缩放、平移、图例切换等),是 Qt 开发中数据可视化的常用工具。
QCustomPlot 是一个基于 Qt C++ 的绘图和数据可视化组件,具有以下核心特点:
- 独立性:无额外依赖,仅需 Qt 环境即可使用。
- 文档完善:提供详细的官方文档和教程,便于快速上手(如「Setting Up」和「Basic Plotting」教程)。
- 核心优势:专注于生成高质量、达到出版标准的 2D 图表,同时支持高性能实时数据可视化。
- 导出功能:可将图表导出为多种格式,包括矢量格式(如 PDF)和栅格图像(如 PNG、JPG、BMP)。
- 适用场景:既能用于应用程序内的实时数据展示,也能生成用于其他媒介的高质量图表。
环境配置
- 完整包(qcustomplot.tar.gz):包含源代码、文档和示例项目
- 共享库包(qcustomplot-sharedlib.tar.gz):含编译共享库的 .pro 文件
- 源码包(qcustomplot-source.tar.gz):仅包含源代码文件
- 下载
QCustomPlot
完整包(官网:Qt Plotting Widget QCustomPlot - Introduction),包含qcustomplot.h
和qcustomplot.cpp
两个文件。 - 将这两个文件添加到 Qt 项目中
提前将qcustomplot.h
和 qcustomplot.cpp
两个文件复制到QT项目中,然后右键点击Header Files 和Source Files中的添加现有文件
运行时可能遇到编译错误:
以下内容在CMakeLists.txt中添加
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS PrintSupport)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS PrintSupport)
//()中为项目路径
include_directories(D:/QT/QTproject/QTCustomPlot)target_link_libraries(项目名称 PRIVATE Qt${QT_VERSION_MAJOR}::PrintSupport)
- 在需要使用的文件中包含头文件:
#include "qcustomplot.h"
。
打开文件后QCustomPlot/qcustomplot/documentation/html在html文件夹中找到index.html这是图表库的一个文档,可以帮助我们更好的学习
核心类
QCustomPlot(图表核心类)
功能:
作为整个图表系统的基础容器,负责统筹所有绘图元素的显示、用户交互和全局配置。
- 管理图层(QCPLayer)系统,控制绘图元素的显示层级(如前景层、背景层)
- 处理用户交互事件(鼠标点击、拖拽、滚轮缩放、双击重置等)
- 提供图表导出功能(支持 PDF、PNG、JPG 等格式)
- 维护坐标轴矩形(QCPAxisRect),默认包含一个主坐标轴矩形,也可添加多个子矩形实现多图布局
- 提供全局样式配置(如背景色、网格线样式、抗锯齿设置等)
依据层的顺序的不同,绘制的顺序也不同,越在底下的层越早绘制,当前层默认为绘图层main,而我们的绘图区域则在QCPAxisRect中 , QCustomPlot类默认包含一个QCPAxisRect ,我们可以在下图中可以看到一个QCPAxisRect一般来说会有 上轴xAxis2 、 下轴xAxis 、 左轴yAxis 和 右轴yAxis2 四个轴
图层:
图层名称(英文) | 中文名称 | 核心作用与特性 |
---|---|---|
background | 背景层 | - 位于最底层,作为整个图表的基础背景。 - 通常用于绘制纯色背景、渐变背景或背景图片(如网格背景图)。 - 不影响其他图层元素的显示,仅提供视觉基底。 |
grid | 网格层 | - 用于绘制坐标轴对应的网格线(主网格、次网格)。 - 每个坐标轴(x 轴、y 轴)会在该层生成独立的网格对象(QCPGrid),可单独控制网格样式(线条颜色、粗细、类型)。 - 位于背景层之上,确保网格线可见但不遮挡核心数据。 |
main | 绘图层 | - 核心数据绘制层,所有绘图元素(如 QCPGraph 折线、QCPBars 柱状图等)默认添加到此层。 - 处于网格层之上、坐标轴层之下,保证数据图形清晰可见且不会被坐标轴遮挡。 - 是图表的 "数据展示核心层",大多数自定义绘图元素会放在此层。 |
axis | 坐标轴层 | - 用于绘制所有坐标轴(轴线、刻度线、刻度标签、轴标签等)。 - 位于绘图层之上,确保坐标轴不会被数据图形遮挡,同时清晰界定绘图区域。 - 坐标轴的交互事件(如拖拽调整范围)也在此层处理。 |
legend | 图例层 | - 用于绘制图例(QCPLegend),展示各绘图元素的标识(如曲线名称、颜色标记)。 - 默认位于图表右上角,可通过设置调整位置(如左上角、底部等)。 - 处于坐标轴层之上,避免被坐标轴遮挡,同时不影响数据图形的核心展示。 |
overlay | 覆盖层 | - 位于最顶层,用于绘制临时或交互相关的元素。 - 典型应用:鼠标选择时的矩形框(QCPSelectionRect)、临时标注、tooltip 提示框等。 - 特性:元素绘制在所有图层之上,确保交互反馈清晰可见,且不会永久修改底层图表结构。 |
常用方法:
***绘图元素管理***
addGraph(QCPAxis *keyAxis=nullptr, QCPAxis *valueAxis=nullptr)
添加折线图(QCPGraph),可指定关联的坐标轴(默认关联主坐标轴)
keyAxis:QCPAxis*(坐标轴指针)
指定折线图(QCPGraph)关联的 x 轴(键轴),默认为主坐标轴矩形的底部 x 轴(axisRect()->axis(QCPAxis::atBottom))
eg:若需使用顶部 x 轴,可传入axisRect()->axis(QCPAxis::atTop)
valueAxis:QCPAxis*
指定关联的 y 轴(值轴),默认为主坐标轴矩形的左侧 y 轴(axisRect()->axis(QCPAxis::atLeft))addBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
添加柱状图(QCPBars),需指定 x、y 坐标轴addPlottable(QCPAbstractPlottable *plottable)
添加自定义绘图元素(所有继承自 QCPAbstractPlottable 的对象)removeGraph(int index) / clearGraphs()
移除指定索引的折线图 / 清除所有折线图***坐标轴矩形***
axisRect(int index=0) 获取第 index 个坐标轴矩形(默认返回主矩形)
addAxisRect() 添加新的坐标轴矩形(用于多子图布局)***交互控制***
setInteractions(QCP::Interactions interactions)
设置允许的交互类型
interactions:QCP::Interactions(枚举值集合,支持按位或|组合)
常用取值:
QCP::iNone:禁用所有交互(默认)
QCP::iRangeDrag:允许拖拽调整坐标轴范围(按住鼠标拖动绘图区)
QCP::iRangeZoom:允许滚轮缩放坐标轴范围
QCP::iSelectPlottables:允许点击选中绘图元素(如曲线、柱状图)
QCP::iSelectAxes:允许选中坐标轴(选中后可拖拽调整位置)
eg:setInteractions(QCP::iRangeDrag | QCP::iRangeZoom) 启用拖拽和缩放
setSelectionTolerance(int pixels) 设置选择元素的容差(鼠标点击与元素的像素距离)***刷新与导出***
replot(QCustomPlot::RefreshPriority priority=rpNormal)
刷新图表(数据或样式更新后必须调用),priority控制刷新优先级
priority:QCustomPlot::RefreshPriority(枚举)
控制刷新优先级,影响图表重绘的时机和性能。
取值:
rpLow:低优先级,适合频繁刷新(如实时数据),可能合并多次刷新请求
rpNormal:正常优先级(默认),立即触发重绘
rpHigh:高优先级,确保立即重绘(如用户交互后)
savePdf(const QString &fileName, int width=-1, int height=-1)
导出图表为 PDF,width/height 为尺寸
fileName:QString
导出文件路径(需包含.pdf扩展名),如"chart.pdf"
width / height:int(像素)
指定导出 PDF 的宽度和高度,-1表示使用当前图表的实际尺寸
savePng(const QString &fileName, int width=-1, int height=-1, int dpi=96)
导出为 PNG 图像,dpi 指定分辨率***样式配置***
setBackground(QBrush brush) 设置图表背景(颜色或纹理)
setAntialiasedElements(QCP::AntialiasedElement elements)
开启指定元素的抗锯齿(如QCP::aeAll开启所有元素抗锯齿)
QCPLayer(图层管理类)
功能:
通过分层机制管理所有可显示元素(QCPLayerable),控制元素的显示优先级和可见性。
- 每个图层有独立的 "可见性" 和 "交互开关",可单独控制某一层是否显示或响应事件
- 图层按 "堆叠顺序" 排序,上层元素会覆盖下层元素(如网格线通常在底层,数据曲线在中间层,标注在顶层)
- QCustomPlot 默认包含多个预定义图层(如
"background"
、"grid"
、"main"
、"axes"
、"overlay"
),也可自定义新图层
常用方法:
***坐标轴管理***
axis(QCPAxis::AxisType type, int index=0)
获取指定类型的坐标轴(如QCPAxis::atBottom获取底部 x 轴,index用于同方向多坐标轴)
type:QCPAxis::AxisType(枚举)
指定坐标轴方向
取值:
QCPAxis::atLeft:左侧 y 轴
QCPAxis::atRight:右侧 y 轴
QCPAxis::atBottom:底部 x 轴
QCPAxis::atTop:顶部 x 轴
index:int
当同一方向有多个坐标轴时,指定索引(默认 0,即第一个轴)
addAxis(QCPAxis::AxisType type, QCPAxis *baseAxis=nullptr)
baseAxis:QCPAxis*
新坐标轴的参考轴,新轴会与参考轴共享刻度范围和网格线(可选,默认为同一方向的主坐标轴)
eg:为右侧添加一个与左侧 y 轴同步的新轴:
addAxis(QCPAxis::atRight, axis(QCPAxis::atLeft))
添加新坐标轴,baseAxis指定参考轴(新轴与参考轴共享刻度范围)
removeAxis(QCPAxis *axis) 移除指定坐标轴***范围控制***
setRange(const QRectF &rect)
设置坐标轴矩形的整体范围(x 从 rect.left () 到 rect.right (),y 同理)
setRangeX(double left, double right)
setRangeY(double top, double bottom) 单独设置 x 或 y 方向的范围
zoom(double factor) 按比例缩放坐标轴矩形(factor>1 放大,<1 缩小)***布局与样式***
setMargins(QMargins margins) 设置坐标轴矩形与图表边缘的边距(上、右、下、左)
margins:QMargins(Qt 类,包含上、右、下、左四个边距值)
设置坐标轴矩形与图表边缘的距离(单位:像素)
eg:setMargins(QMargins(20, 20, 20, 20)) 表示四周各留 20 像素边距
setMinimumSize(int width, int height) 设置坐标轴矩形的最小尺寸(像素)
setBackground(QBrush brush) 设置坐标轴矩形的背景(区别于 QCustomPlot 的全局背景)
QCPAbstractPlottable(绘图元素基类)
功能:
所有具体绘图类型的抽象基类,定义了绘图元素的通用接口(如数据设置、样式配置、选中状态等)。
派生类包括多种常用图表类型,每种类型针对特定数据展示需求优化:
- QCPGraph(折线图):最常用类型,用于展示连续数据的趋势(如时间序列、函数曲线),支持线条样式、点标记自定义
- QCPCurve(曲线图):适用于参数化曲线(如圆、贝塞尔曲线),通过参数方程定义 x、y 坐标
- QCPBars(柱状图):用于对比离散类别数据,支持多组数据并列 / 堆叠显示,可设置柱宽、颜色等
- QCPStatBox(盒子图):用于统计数据分布,展示中位数、四分位数、异常值等统计特征。
- QCPColorMap(色谱图):通过颜色梯度展示二维数据分布(如热图),需配合颜色映射(QCPColorScale)使用
- QCPFinancial(金融图):专为金融数据设计,支持 K 线图(蜡烛图)、OHLC 图(开盘 / 最高 / 最低 / 收盘价图)
- 通用特性:
- 所有绘图元素均需关联坐标轴(xAxis、yAxis)以确定数据的显示范围
- 支持设置选中样式(如选中时线条变粗、颜色变化),配合交互事件实现元素选择功能
QCPAxisRect(坐标轴矩形类)
功能:
管理一组坐标轴的容器,定义图表的绘图区域边界,支持多坐标轴布局。
- 默认配置:
- 一个 QCPAxisRect 默认包含 4 个坐标轴:
xAxis
(底部)、xAxis2
(顶部)、yAxis
(左侧)、yAxis2
(右侧) - 坐标轴默认共享刻度范围(如 xAxis 和 xAxis2 范围一致),也可独立设置
- 一个 QCPAxisRect 默认包含 4 个坐标轴:
- 扩展能力:
- 支持添加额外坐标轴(如
addAxis()
方法),实现多数据系列共享同一绘图区但使用不同刻度(如左侧 y 轴显示温度,右侧 y 轴显示湿度 - 可在 QCustomPlot 中添加多个 QCPAxisRect,实现 "多子图" 布局(如上下分栏、左右分栏显示不同图表)
- 支持添加额外坐标轴(如
常用方法:
基础属性
setVisible(bool visible) 设置图层是否可见(false 时该层所有元素隐藏)
setInteractionEnabled(bool enabled)
设置图层元素是否响应交互事件(false 时无法选中或拖拽该层元素)
isVisible() / interactionEnabled() 获取图层可见性 / 交互状态元素管理
addLayerable(QCPLayerable *layerable, bool takeOwnership=true)
向图层添加元素,takeOwnership为 true 时图层负责释放元素内存
layerable:QCPLayerable*(所有可显示元素的基类指针,如 QCPGraph、QCPBars 等)
指定要添加到图层的元素
takeOwnership:bool
若为true,图层将接管元素的内存管理(销毁图层时自动释放元素)
若为false,需手动释放元素内存(避免重复释放)
removeLayerable(QCPLayerable *layerable) 从图层移除元素(不释放内存)
layerables() 返回图层中所有元素的列表(QList<QCPLayerable*>)层级调整
moveAbove(QCPLayer *other)
moveBelow(QCPLayer *other)
other:QCPLayer*(目标图层指针)
将当前图层移动到other图层的上方(moveAbove)或下方(moveBelow),控制显示层级(上层元素覆盖下层)
将当前图层移到另一个图层上方 / 下方(调整显示优先级)
stackingIndex() 返回图层的堆叠索引(值越大越靠上)
结语:
无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力