qt QCustomPlot学习
QCustomPlot 是一个基于Qt的画图和数据可视化C++控件。QCustomPlot 致力于提供美观的界面,高质量的2D画图、图画和图表,同时为实时数据可视化应用提供良好的解决方案。 该绘图库专注于制作美观、出版物质量高的2D绘图、图形和图表,并为实时可视化应用程序提供高性能。
QCustomPlot的几个重要类
QCustomPlot 图表类:用于图表的显示和交互;
QCPLayer 图层:管理图层元素(QCPLayerable)
QCPLayerable图层元素:所有可显示的对象都是继承自图层元素;
QCPAbstractPlottable 绘图元素:包含 折线图(QCPGraph)、曲线图(QCPCurve)、柱状图(QCPBars)、QCPStatiBox(盒子图)、QCPColorMap(色谱图)、QCPFinancial(金融图);
QCPAxisRect 坐标轴矩形:一个坐标轴矩形默认包含上下左右四个坐标轴,但是可以添加多个坐标轴;

QCustomPlot下载
下载地址:https://www.qcustomplot.com/index.php/download
选择版本2.1.0 QCustomPlot.tar.gz
QCustomPlot 的使用
解压下载的文件
把qcustomplot.h和qcustomplot.cpp放到自己的项目工程(复制文件并qt 的目录树添加存在的头文件源文件)。在使用QCustomPlot类的地址包含头文件 #include "qcustomplot.h"
拖拽控件提升类
在UI Designer中,可以拖动一个Widget控件到ui设计器上,对这个窗体点击右键,选择提升QCustomPlot



如果是代码方式添加就不需要对控件提升的这布操作,直接使用QCustomPlot 类声明对象即可。如
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);QCustomPlot *mPlot = new QCustomPlot(this);setCentralWidget(mPlot);
}
添加printsupport
如果Qt版本在5.0以上,需要在.pro文件中的QT变量加上printsupport:
QT += widgets printsupport
添加帮助文档
在下载的documentation文件夹下有个qcustomplot.qch文件,将它拷贝Qt的安装文档目录下(一般为qt5.9\Docs\Qt-5.9,会根据你的Qt版本号而做相应变动),然后在QtCreator ——>工具——>选项——>帮助——>文档——>添加,选择qcustomplot.qch文件,确定,以后按F1就能跳转到QCustomPlot的帮助
绘制具体图形
QVector<double> x(101), y(101); //初始化向量x和yfor (int i=0; i<101; ++i){x[i] = i/50.0 - 1; // x范围[-1,1]y[i] = x[i]*x[i]; // y=x*x}mPlot->addGraph();//添加数据曲线(一个图像可以有多个数据曲线)mPlot->setViewport(QRect(0,0,400,400));// graph(0);可以获取某个数据曲线(按添加先后排序)// setData();为数据曲线关联数据mPlot->graph(0)->setData(x, y);mPlot->graph(0)->setName("第一个示例");// 设置图例名称// 为坐标轴添加标签mPlot->xAxis->setLabel("x");mPlot->yAxis->setLabel("y");// 设置坐标轴的范围,以看到所有数据mPlot->xAxis->setRange(-1, 1);mPlot->yAxis->setRange(0, 1);mPlot->legend->setVisible(true); // 显示图例// 重画图像mPlot->replot();
实战心得
显示折线图(QCPGraph),调用QCustomPlot类的addGraph函数,表示添加一条曲线。
removeGraph //表示删除一条曲线
从QCustomPlot调用graph函数,则得到一条具体的曲线(QCPGraph类指针)。
曲线设置数据源,则调用QCPGraph的setData函数。
customPlot->graph(0)->data().data()->clear();//清空数据
刷新整个图表 customPlot->replot();//刷新
通过QCustomPlot的成员变量指针 xAxis,yAxis,则获取数值坐标轴(QCPAxis)。
类介绍
QCustomPlot
addGraph 添加曲线
如果keyAxis和valueAxi为空,则底部(xAxis)用作键,左边(yAxis)用作值轴;如果指定,keyAxis和valueAxis必须位于
removeGraph 删除图元
graph 获取图元
addLayer //创建一个图层
setCurrentLayer
removeLayer //删除一个图层不会删除图层对应的的对象
layer、currentLayer 获取图层
axisRects //获取坐标轴的矩形区域
QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; //坐标
QCPLegend *legend; //图例
QCPLayer 图层
Layer是可能包含对象的、控制渲染顺序的对象。对于QCustomPlot对象内部具有一个渲染顺序列表,在绘制时将会连续画出QCPLayerable对象。
QCPLayer包含有序的QCPLayerable对象。
构造函数QCPLayer(QCustomPlot* parentPlot, const QString &layerName);
父对象为QCustomPlot对象
QCPLayer和QCustomPlot的关系:调用QCustomPlot的currentLayer或者layer获取图层
默认图层
背景层、网格层、主层、坐标轴层、图例层和矩形选择区域层。
默认情况下,QCustomPlot有六个图层,分别是:“background” “grid” “main” “axes” “legend”和“overlay”(注意顺序)。最先绘制的是“overlay”层,它只包含QCustomPlot选中的矩形(QCustomPlot::selectionRect)。往后分别是“axes”和“legend”,表示默认轴和图例。在中间,有一个“main”层,它默认不含任何东西且为默认图层(QCustomPlot::setCurrentLayer)。这也就意味着所有可绘制的对象将会默认在此层。接着是QCPGrid对象(与QCPAxis紧密相连)background在最后面。当然你可以设置每个对象所在的图层(QCPLayerable::setLayer)。
控制图层渲染顺序
在绘制时控制图层非常简单:使用QCustomPlot::addLayer方法创建一个指定层的图层,如在“main”上层,然后用QCustomPlot::setCurrentLayer设置设置为你刚刚创建的图层,接下来的事情,只需要和往常一样创建图层上的对象即可,因为你设置了当前图层,所以对象都将会放置在该图层。在同一图层内点的对象是覆盖形式的,删除一个图层不会删除对应的的对象QCustomPlot::removeLayer
常用的函数:
1.QList<QCPLayerable*> children() //获取当前图层的所有图元
QCPLayerable
QCPLayerable是所有可见对象的基类,如:axes、grids、graph和item等。

QCPGraph 折线
构造函数explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis);
如果keyAxis和valueAxi为空,则底部(xAxis)用作键,左边(yAxis)用作值轴
常用函数
设置曲线的字体颜色、画刷 setPen、setBrush
设置曲线的风格 setLineStyle
设置每个点的风格 setScatterStyle
设置数据 setData

折线的类继承关系
QCPGraph和QCustomPlot的关系:QCustomPlot调用addGraph得到QCPGraph指针。
QCPAxis
QCPAxis 描述轴行为,轴需要依赖QCPAxisRect
QCPAxisRect 描述矩形区域,区域依赖于QCPCustomPlot
构造函数 QCPAxis::QCPAxis (QCPAxisRect * parent, AxisType type);
可以看出QCPAxis依赖与QCPAxisRect对象的。
QCPAxis和QCustomPlot的关系:QCustomPlot有成员变量QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;


常用函数
QCPAxisRect *axisRect() //得到矩形区域
setLabel //设置名称
setVisible //坐标轴是否显示
setTickLabels //tick Label 是否显示
setLabelColor setTickLabelFont //设置坐标轴数字字体和颜色
setRange //设置坐标轴范围
自定义坐标轴
调用QCPAxis的setTicker函数
QCPAxisTicker是坐标轴的基类


QCPAxisTickerDateTime类是日期时间坐标轴
QCPAxisTickerTime是时间轴刻度类
QCPAxisTickerPi设置Pi刻度标签
QCPAxisTickerLog设置log对数刻度标签
QCPAxisTickerFixed定义轴标尺修改指定的步长控制坐标轴刻度的数目
void setupTestQCPAxisTickerDateTime()
{customPlot->setInteraction(QCP::iRangeDrag, true);customPlot->setInteraction(QCP::iRangeZoom, true);QDateTime dateTime = QDateTime::currentDateTime();double now = dateTime.toTime_t();//当前时间转化为秒//生成时间刻度对象QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);customPlot->xAxis->setTicker(dateTimeTicker);//dateTimeTicker->setDateTimeSpec(Qt::UTC);//设施世界时间,即不加上时区的时间dateTimeTicker->setTickCount(12);dateTimeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);customPlot->xAxis->setSubTicks(false);customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时QVector<double> yData, xData;//生成数据for (int i = 0; i <= 24; i++){xData.push_back(now + i * 3600.0);yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));}dateTimeTicker->setDateTimeFormat("yyyy-M-d h:m");//设置x轴刻度显示格式customPlot->xAxis->setTickLabelRotation(30);//设置刻度标签顺时针旋转30度customPlot->yAxis->setRange(-1000,10000);customPlot->addGraph();customPlot->graph(0)->setData(xData, yData);//显示数据
}
3.运行结果图:
QCPAxisRec 矩形区域
QCPAxisRect是多个轴围成的一个矩形区域,也就是坐标轴.
构造函数 QCPAxisRect (QCustomPlot *parentPlot, bool setupDefaultAxes=true);
第一个参数是父对象QCustomplot,第二个参数是否设置默认轴(四个轴,但是只显示左下)。构造函数告诉我们,QCPAxisRec必须依赖与一个父对象QCustomPlot。
常用函数
addAxis //添加一个轴
QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=nullptr);
第二个参数是一个QCPAxis对象指针,
轴由内部创建。axis 为空指针,表示由内部创建并维护这个轴的生命周期,请不要直接delete返回的轴指针,而是使用removeAxis删除;
轴是外部实例。axis为指向实例的指针,表示这个轴是用户自行创建的,
removeAxis 移除特定轴
axis、axes 获取坐标区域的坐标轴
QCPAxisRect和QCustomPlot的关系:QCustomPlot调用axisRects得到获取坐标轴的矩形区域对象指针。
QCPLegend 图例
该对象管理了一个QCustomPlot的一个图例。它是一个小的Box区域,包含名称和图标。通过QCPAbstarctPlottable::adddToLegend来填充QCPLegend内容,对于主图示(QCustomPlot::legend)仅需设置QCustomPlot::setAutoAddPlottableToLegend为true(默认行为)就可以自动创建一些legend项,legend是一个与特定可绘制对象相关的对象,可以被QCPAbstractPlottable::removeFromLegend去除。
此外,QCPLegend提供了一些接口增加和直接管理这些legend:item、itemWithPlottable、itemCount、addItem、removeItem等。因为QCPLegend是从QCPLayoutGrid继承而来的,因此通过对象QCPLayoutElement可以将legend添加到任意位置,legend是QCPLayoutElement的元素,默认情况下每一个QCustomPlot只有一个legend(QCustomPlot::legend),表示主轴的内嵌布局中(QCPAxisRect::insetLayout),你可以通过QCPLayoutInset实现在矩形区域移动,使用QCPLayout/QCPLayoutElement接口实现矩形外移动。

常用的函数:
setVisible、setFont、setTextColor设置legend是否显示,字体大小、颜色
removeItem 设置不显示哪一项
设置图例位置,这里设置左上角
customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignLeft | Qt::AlignTop);
相关文章:

qt QCustomPlot学习
QCustomPlot 是一个基于Qt的画图和数据可视化C控件。QCustomPlot 致力于提供美观的界面,高质量的2D画图、图画和图表,同时为实时数据可视化应用提供良好的解决方案。 该绘图库专注于制作美观、出版物质量高的2D绘图、图形和图表,并为实时可视…...
【HDFS】FsDatasetImpl系列文章(七):finalizeBlock方法和unfinalizeBlock方法
一、finalizeBlock 1.1 调用点&调用场景 主要用于完成block的写入。调用点有两处: ① BlockReceiver#receiveBlock方法里: 这个调用场景发生在:datanode在所有的packet都接收完了之后,如果是数据复制、balancer、或者stage是TRANSFER_FINALIZED的情况下,调用finaliz…...

测试部门来了个99年的卷王之王,老油条感叹真干不过,但是...
在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事,我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事,可遇不可求,向他学习还来不及呢。 真正让人反感的,是技术平平&…...

CSS 网页动画【快速掌握知识点】
目录 前言 一、使用CSS3动画 二、使用CSS过渡 三、使用CSS变换: 前言 CSS是一种用于网页设计和排版的语言,也可以用它来制作网页动画。 一、使用CSS3动画 CSS3引入了动画属性,允许您为元素设置动画效果。您可以使用关键帧来定义动画的开始…...

电脑技巧:分享六个非常实用的资源网站
今天小编给大家分享六个非常实用的资源网站,大家一起来看看吧! 1、高清壁纸:Wallhaven 一个免费的高清壁纸下载网站,里面的壁纸资源丰富,更新速度也快,各种类型的壁纸都能找到,尤其是动漫壁纸。…...

【Java基础 下】 027 -- 异常、File、综合案例
目录 一、异常 1、异常的分类 ①、Error ②、Exception ③、小结 2、编译时异常和运行时异常 ①、编译时异常 ②、运行时异常 ③、为什么异常要分成编译时异常和运行时异常? ④、小结(运行时异常和编译时异常的区别) 3、异常的作用 ①、查看b…...

教师管理系统的设计与实现
技术:Java、JSP等摘要:1.1 计算机管理教师的意义近年来,随着经济的发展,教育正面向着大型化、规模化的方向发展,教师数量急剧增加,有关教师的各种信息量也成倍增长。在这种情况下用计算机可使人们从繁重的劳…...
【Java】线程使用方式
(1)继承 Tread 类 继承Thread类,创建一个新的线程类重写run()方法,将需要并发执行的业务代码编写在run()方法中 //继承Thread来创建一个线程类 class MyThread extends Thread{Overridepublic void run(){System.out.println("hello Thread"…...

零基础想转行学习Python,该如何学习,有学习路线分享吗?(2023年给初学者的建议)
Python属于一种面向对象、解释性的高级语言,它如今在众多领域都被应用,包括操作系统管理、Web开发、服务器运维的自动化脚本、科学计算、桌面软件、服务器软件(网络软件)、游戏等方面,且Python在今后将被大规模地应用到大数据和人工智能方面。…...

IDEA Maven install Failed to execute goal org.apache.maven.plugins异常处理
目录一、异常错误二、原因三、解决方法修改pom.xml资源配置文件一、异常错误 由于服务器编译拦截了静态资源,导致出现异常,需要重新打包编译 打开IDEA带的Maven管理,双击clean清除由项目编译创建的target 再双击install安装jar包到本地仓库…...

TensorFlow-Keras - FM、WideAndDeep、DeepFM、DeepFwFM、DeepFmFM 理论与实战
目录 一.引言 二.浅层模型概述 1.LR 2.FM 3.FMM 4.FwFM 5.FmFM 三.常用推荐算法实现 Pre.数据准备 1.FM 2.WideAndDeep 3.DeepFM 4.DeepFwFM 5.DeepFmFM 四.总结 1.函数测试 2.函数效果与复杂度对比[来自FmFM论文] 3.More 一.引言 推荐系统中常见的 CTR 模型…...

Java浅析电信数据采集
技术:Java等摘要:电信运营系统中,电信计费系统是主要的支撑系统,占有重要地位。对于电信计费系统是电信运营商的核心竞争力之一这一观点愈来愈被业界认同。电信计费系统中的数据蕴含着企业经营态势、客户群分布特征及消费习惯、各…...

那些开发中需要遵守的产研开发规范
入职新公司第三天,没干啥其他活,基本在阅读产研开发规范。公司在技术方面沿用的是阿里的一套技术,所以入职之前需要先阅读《阿里巴巴开发规范》。今天整理一些平时需要关注的阿里规约和数据库开发规范,方便今后在开发过程中查阅。…...

一文深入分析-内核并发消杀器(KCSAN)
一、KCSAN介绍 KCSAN(Kernel Concurrency Sanitizer)是一种动态竞态检测器,它依赖于编译时插装,并使用基于观察点的采样方法来检测竞态,其主要目的是检测数据竞争。 KCSAN是一种检测LKMM(Linux内核内存一致性模型)定义的数据竞争(data race…...
Java学习-IO流-字符缓冲流
Java学习-IO流-字符缓冲流 字符缓冲流↙ ↘ BufferedReader BufferedWtrier 字符缓冲输入流 字符缓冲输出流底层自带长度为8192的缓冲区提高性能 public BufferedReader(Reader r):把基本流包装成高级流 public BufferedWtrier(Wtrier w):把…...
Java的一维数组遍历、求最值、冒泡排序
一.数组遍历: Example: import java.util.ArrayList; public class App { public static void main(String[] args) { int[]arr{1,2,3,4,5}; for(int i0;i<arr.length;i){ System.out.println(arr[i]); } } 运行结果:12345 定义了一…...

Free for photo container detection, container damage detect PaaS
集装箱箱号识别API免费,飞瞳引擎集装箱人工智能平台,可通过API二次开发或小程序拍照使用,可二次开发应用码头港区海关仓库口岸铁路场站船公司堆场,实现云端集装箱信息识别/集装箱箱况残损检测/好坏箱检验,高检测率/高实…...
【golang】【源代码】reflect.DeepEqual(x,y)函数
reflect.DeepEqual(x, y)函数 功能是比较x和y是否一致,x和y不仅限于基础类型,也可以是像array、 slice、 map、 ptr、struct、interface类型,在代码中经常能见到。 一起看下是怎么实现的吧~ func DeepEqual(x, y interface{}) bool {if x …...
Python实现定时执行脚本(4)
前言 本文是该专栏的第16篇,后面会持续分享python的各种干货知识,值得关注。 在项目开发中,难免会需要用到定时任务。比如说,在某个时间段,甚至是达到某时某分某秒自动运行你部署好的功能脚本。而在本专栏的前面,笔者有详细介绍过3种使用python执行定时脚本的方法。 1.…...
量子力学(4) 全同粒子
如果势能与时间无关,那么Ψψe−iEt/ℏ\Psi\psi e^{-iEt/\hbar}Ψψe−iEt/ℏ,EEE是系统的总能量。 全同粒子分为玻色子和费米子。所有电子是全同的费米子。所有质子是全同的费米子。全同就是说不可能区分出其中的一个,比如说你摇了五个骰子…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...