Qt——示波器/图表 QCustomPlot

一、介绍

    QCustomPlot是一个用于绘图和数据可视化的Qt C++小部件。它没有进一步的依赖关系,提供友好的文档帮助。这个绘图库专注于制作好看的,出版质量的2D绘图,图形和图表,以及为实时可视化应用程序提供高性能。QCustomPlot可以导出各种格式,如矢量化的PDF文件和光栅化的图像,如PNG, JPG和BMP。QCustomPlot是用于在应用程序中显示实时数据以及为其他媒体生成高质量图的解决方案。

在这里插入图片描述

二、配置

1)下载
官方网站
http://www.qcustomplot.com/

    从官网下载文件,选择2.1版本以上,因为这会开始支持Qt6了。可以选择源文件+实例+说明文档全部下载,或者选择下载单动态库或纯源码,文件不大建议全部下载。

在这里插入图片描述

2)QtCreator配置
新建一个Qt Widgets Application工程。

在这里插入图片描述

     把下载好的qcustomplot.h和qcustomplot.cpp放到工程下,右击项目,添加现有文件。

在这里插入图片描述

    对话框中选择选择qcustomplot.h和qcustomplot.cpp文件添加到项目中,并在pro文件中添加Qt += printsupport。

在这里插入图片描述

    双击mainwindows.ui进入Designer界面,新建一个widget部件。

在这里插入图片描述

     右击widget部件,选择提升为...。

在这里插入图片描述

     在类名称里面输入QCustomPlot,选择“添加”,然后选择“提升”。这里要注意头文件路径,如果你是放在最外层(和pro文件同级),直接默认值就行。如果是放在某文件夹下,比如新建了一个custom文件夹并放置在里面,那么头文件这一栏应该是“custom/qcustomplot.h”。

在这里插入图片描述

     提升之后,widget类已经被改成QCustomPlot。

在这里插入图片描述

     在mianwindows.cpp构造函数添加如下demo代码。        

// add two new graphs and set their look:
ui->widget->addGraph();
ui->widget->graph(0)->setPen(QPen(Qt::blue)); // line color blue for first graph
ui->widget->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); // first graph will be filled with translucent blue
ui->widget->addGraph();
ui->widget->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph
// generate some points of data (y0 for first, y1 for second graph):
QVector x(251), y0(251), y1(251);
for (int i=0; i<251; ++i)
{
x[i] = i;
y0[i] = qExp(-i/150.0)*qCos(i/10.0); // exponentially decaying cosine
y1[i] = qExp(-i/150.0); // exponential envelope
}
// configure right and top axis to show ticks but no labels:
// (see QCPAxisRect::setupFullAxesBox for a quicker method to do this)
ui->widget->xAxis2->setVisible(true);
ui->widget->xAxis2->setTickLabels(false);
ui->widget->yAxis2->setVisible(true);
ui->widget->yAxis2->setTickLabels(false);
// make left and bottom axes always transfer their ranges to right and top axes:
connect(ui->widget->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget->xAxis2, SLOT(setRange(QCPRange)));
connect(ui->widget->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget->yAxis2, SLOT(setRange(QCPRange)));
// pass data points to graphs:
ui->widget->graph(0)->setData(x, y0);
ui->widget->graph(1)->setData(x, y1);
// let the ranges scale themselves so graph 0 fits perfectly in the visible area:
ui->widget->graph(0)->rescaleAxes();
// same thing for graph 1, but only enlarge ranges (in case graph 1 is smaller than graph 0):
ui->widget->graph(1)->rescaleAxes(true);
// Note: we could have also just called ui->widget->rescaleAxes(); instead
// Allow user to drag axis ranges with mouse, zoom with mouse wheel and select graphs by clicking:
ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    编译构建项目成功后,执行即可看到demo图表。

在这里插入图片描述

3)添加说明文档
下载的文档可以直接添加到QtCreator的帮助里面。

在这里插入图片描述

    把文件放到 D:\Qt\Qt5.9.6\Tools\QtCreator\share\doc\qtcreator底下

在这里插入图片描述

     QtCreator选择工具-选项。

在这里插入图片描述

     选择-文档-添加,在弹出的界面选择把qcustomplot.qch文件加进来。

在这里插入图片描述

     如此,我们在帮助界面搜索qcustomplot就可以直接浏览帮助文档。         ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b47d85cd4eaa4d8dad4300c796aee8dc.png#pic_center)

三、常用功能详解

1)曲线
使用addGraph()方法新建曲线,返回一个QCPGraph对象指针,后续使用此指针或者根据索引获取指针对曲线动作。

    建议使用保存对象指针方法操作曲线,因为索引容易误操作,比如当新建两条曲线的时候,删除第一条,第二条索引会从1变成0,高亮的时候索引也会有异常。

//初始化返回类指针
QCPGraph *graph1 = ui->plot->addGraph();
//根据索引获取类指针
QCPGraph *graph1 = ui->plot->graph(index)
如果你需要两条曲线在不同的坐标系,比如X轴相同,Y轴不同,那么就需要在初始化的时候指定坐标系,或者后续指定。

QCPGraph *graph1 = ui->plot->addGraph(ui->plot->xAxis,ui->plot->yAxis);
QCPGraph *graph2 = ui->plot->addGraph(ui->plot->xAxis,ui->plot->yAxis2);

//或者在addGraph之后使用
graph1->setKeyAxis(ui->plot->xAxis);
graph1->setValueAxis(ui->plot->yAxis);
graph2->setKeyAxis(ui->plot->xAxis2);
graph2->setValueAxis(ui->plot->yAxis2);
使用setData()方法设置曲线坐标数据,坐标数据使用QVector封装,使用此方法会覆盖原先的曲线。注意这里x和y的动态数组长度要一致,否则控制台会报错并失效。

QVector x0(251), y0(251);
for (int i=0; i<251; ++i)
{
x[i] = i;
y0[i] = qExp(-i/150.0)*qCos(i/10.0);
}
ui->plot->graph(0)->setData(x0,y0);//写入数据
使用addData()方法在原先基础上添加数据,适用于动态曲线,当然如果一直重新setData也是可以,不建议这么做。

ui->plot->graph(0)->addData(x0, y0)
使用clear()清空数据,但是曲线还保留着。

ui->plot->graph(0)->data()->clear();
使用setName()方法设置曲线名称,name方法返回曲线名称。

ui->plot->graph(0)->setName(QString(“graph1”));
qDebug()<Plot->graph(0)->name();
使用removeGraph()方法传入QCPGraph指针或者索引移除曲线。

ui->plot->removeGraph(0);
ui->plot->removeGraph(graph1);
设置曲线画笔颜色、宽度、样式。

ui->plot->graph(0)->setPen(QPen(QColor(120, 120, 120), 2));
设置曲线使用刷子。

ui->plot->graph(1)->setBrush(QColor(200, 200, 200, 20));

在这里插入图片描述

    使用setChannelFillGraph()把通道2包含在1里面,这样刷子颜色就不会透视。

QCPGraph *graph2 = ui->widget->addGraph();
graph2->setData(x2, y2);
graph2->setPen(Qt::NoPen);
graph2->setBrush(QColor(200, 200, 200, 20));
graph2->setChannelFillGraph(graph1);

在这里插入图片描述

     使用setScatterStyle()设置曲线散点的样式。

ui->plot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::black, 1.5), QBrush(Qt::white), 9));
在这里插入图片描述

2)柱状图
实例化QCPBars()。

QCPBars *bars1 = new QCPBars(ui->widget->xAxis, ui->widget->yAxis);
使用setWidth()设置柱状图宽度

bars1->setWidth(10);
使用setPen()设置画笔

bars1->setPen(QPen(QColor(120, 120, 120), 2));
使用setBrush()设置刷子颜色填充。

bars1->setBrush(QColor(10, 140, 70, 160));
使用moveAbove()设置栏2在1的上方。

bars2->moveAbove(bars1);
在这里插入图片描述

3)坐标轴
在这里插入图片描述

    使用setVisible()方法设置是否显示。

ui->plot->xAxis2->setVisible(true);
ui->plot->yAxis2->setVisible(true);
使用setTickLabels()方法设置是否显示刻度。

ui->widget->xAxis2->setTickLabels(false);
ui->widget->yAxis2->setTickLabels(false);
使用rescaleAxes()方法设置自适应坐标轴,防止因为坐标轴范围过长而出现大量无数据地带

ui->Plot->graph(0)->rescaleAxes();
使用setRange()设置坐标轴范围,使用range()获取坐标轴范围数值。

ui->plot->xAxis->setRange(0, 100);
ui->plot->yAxis->setRange(0, 100);
QCPRange XAxis_Range=ui->plot->xAxis->range();
缩放、自适应等会触发rangeChanged()信号,同步使用setRange(),保证上下、左右坐标一致。

connect(ui->plot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->xAxis2, SLOT(setRange(QCPRange)));
connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange)));
3)样式
使用setTickLabelColor()设置坐标轴标签的颜色。

ui->plot->xAxis->setTickLabelColor(Qt::red);
ui->plot->yAxis->setTickLabelColor(Qt::red);
使用setTickPen()设置含标签的刻度的画笔的颜色、线宽和样式。

ui->widget->xAxis->setTickPen(QPen(Qt::red, 1));
ui->widget->yAxis->setTickPen(QPen(Qt::red, 1));
使用setSubTickPen()设置不含标签的刻度的画笔的颜色、线宽和样式。

ui->widget->xAxis->setSubTickPen(QPen(Qt::red, 1));
ui->widget->yAxis->setSubTickPen(QPen(Qt::red, 1));
使用setBasePen()设置坐标轴画笔的颜色、线宽和样式。

ui->plot->xAxis->setBasePen(QPen(Qt::red, 1));
ui->plot->yAxis->setBasePen(QPen(Qt::red, 1));
使用setSubGridVisible()设置是否显示二级网格。

ui->plot->xAxis->grid()->setSubGridVisible(true);
ui->plot->yAxis->grid()->setSubGridVisible(true);
在这里插入图片描述

    使用setPen()设置网格的画笔的颜色、线宽和样式。

ui->plot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
ui->plot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
使用setSubGridPen()设置二级网格的画笔的颜色、线宽和样式。

ui->plot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
ui->plot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
使用setZeroLinePen()设置零线的画笔的颜色、线宽和样式。

ui->plot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
ui->plot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
使用setBackground()设置背景颜色,设置渐变色,也可以直接使用图片,纯色刷子来当背景。

QLinearGradient plotGradient;
plotGradient.setStart(0, 0);
plotGradient.setFinalStop(0, 350);
plotGradient.setColorAt(0, QColor(80, 80, 80));
plotGradient.setColorAt(1, QColor(50, 50, 50));
ui->plot->setBackground(plotGradient);

QLinearGradient axisRectGradient;
axisRectGradient.setStart(0, 0);
axisRectGradient.setFinalStop(0, 350);
axisRectGradient.setColorAt(0, QColor(80, 80, 80));
axisRectGradient.setColorAt(1, QColor(30, 30, 30));
ui->widget->axisRect()->setBackground(axisRectGradient);
使用setUpperEnding()设置上轴结束的样式。

ui->plot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
ui->plot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);

在这里插入图片描述

4)图例

在这里插入图片描述

    使用setVisible()设置图例是否显示。

ui->plot->legend->setVisible(true);
使用setFillOrder()设置图例信息的水平方向。

ui->plot->legend->setFillOrder(QCPLayoutGrid::foColumnsFirst);

在这里插入图片描述

     使用addElement()设置图例显示的坐标、位置和比例。

ui->plot->plotLayout()->addElement(1 , 0, ui->plot->legend);
在这里插入图片描述

    使用setBorderPen()设置图例边框颜色、线宽、样式。

ui->plot->legend->setBorderPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
使用setRowStretchFactor()设置显示比例,图例所在框的大小。

ui->plot->plotLayout()->setRowStretchFactor(1, 0.001);
5)其他
使用setInteractions()方法设置交互策略

ui->Plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
//放大拖拽选中等枚举
enum Interaction { iRangeDrag = 0x001 //左键点击可拖动
,iRangeZoom = 0x002 //范围可通过鼠标滚轮缩放
,iMultiSelect = 0x004 //可选中多条曲线
,iSelectPlottables = 0x008 //线条可选中
,iSelectAxes = 0x010 //坐标轴可选
,iSelectLegend = 0x020 //图例是可选择的
,iSelectItems = 0x040 //可选择项(矩形、箭头、文本项等
,iSelectOther = 0x080 //所有其他对象都是可选的
};
使用replot()重新启动绘制,当你需要一条动态曲线的时候,除了动态的addData(),还需要不断的使用replot()进行后续的绘制。

ui->plot->replot();
保存成Pdf、Png、Jpg、Bmp格式文件。

bool savePdf (const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())

bool savePng (const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)

bool saveJpg (const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)

bool saveBmp (const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)

在这里插入图片描述

     图例与曲线选中状态绑定。

//响应图例被选中信号
connect(ui->channelChart,&QCustomPlot::legendClick,
this,[=](QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event){
m_grap_A->setSelection(ui->channelChart->legend->item(0)->selected()?
QCPDataSelection(m_grap_A->data().data()->dataRange()):
QCPDataSelection());

}

//响应曲线被选中信号
connect(ui->channelChart,&QCustomPlot::plottableClick,
this,[=](QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event){
ui->channelChart->legend->item(0)->setSelected(m_grap_A->selected());
}

在这里插入图片描述

    QPen样式

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/304755.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决 VSCode 编辑器点击【在集成终端中打开】出现新的弹框

1、问题描述 在 VSCode 的项目下&#xff0c;鼠标右键&#xff0c;点击【在集成终端中打开】&#xff0c;出现新的一个弹框。新版的 VSCode 会有这个问题&#xff0c;一般来说我们都希望终端是在 VSCode 的控制台中打开的&#xff0c;那么如何关闭这个弹框呢&#xff1f; 2、解…

浅谈一下数据接口怎么方便我们的工作

最近一段时间&#xff0c;一直在折腾自己工作上面的一些事情&#xff0c;这几天终于稍微闲下来去做一份表格。 这份表格是基于一款游戏的数据接口去做一个动态的运算&#xff0c;核算出相关的利润率等等的数据。那么我们今天来具体聊聊Excel的获取数据功能。 现在比较多应用都…

VUE3和SpringBoot实现ChatGPT页面打字效果SSE流式数据展示

在做这个功能之前&#xff0c;本人也是走了很多弯路&#xff08;花了好几天才搞好&#xff09;&#xff0c;你能看到本篇博文&#xff0c;那你就是找对地方了。百度上很多都是使用SseEmitter这种方式&#xff0c;这种方式使用的是websocket&#xff0c;使用这种方式就搞复杂了&…

Java项目:基于SSM+vue框架实现的人力资源管理系统设计与实现(源码+数据库+毕业论文+任务书)

一、项目简介 本项目是一套基于SSM框架实现的人力资源管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

WEB漏洞-文件上传之WAF绕过及安全修复

#上传参数解析&#xff1a; Content-disposition&#xff1a;一般不可更改 Name&#xff1a;表单参数值&#xff0c;不能更改&#xff08;更改需要达到统一&#xff09; Filename&#xff1a;文件名&#xff0c;可以更改 Content-type&#xff1a;文件MIME&#xff0c;视情…

从零开始:构建、打包并上传个人前端组件库至私有npm仓库的完整指南

文章目录 一、写组件1、注册全局组件方法2、组件13、组件2 二、测试三、发布1、配置package.json2、生成库包3、配置发布信息4、发布 四、使用1、安装2、使用 五、维护1、维护和更新2、注意事项 一、写组件 确定组件库的需求和功能&#xff1a;在开始构建组件库之前&#xff0c…

【51单片机入门记录】RTC(实时时钟)-DS1302应用

目录 一、DS1302相关写函数 &#xff08;1&#xff09;Write&#xff3f;Ds1302 &#xff08;2&#xff09;Write&#xff3f;Ds1302&#xff3f;Byte 二、DS130相关数据操作流程及相关代码 &#xff08;1&#xff09;DS1302初始化数据操作流程及相关代码 (shijian[i]/10&…

4.9号驱动

1. ARM裸机开发和Linux系统开发的异同 相同点&#xff1a;都是对硬件进行操作 不同点&#xff1a; 有无操作系统 是否具备多进程多线程开发 是否可以调用库函数 操作地址是否相同&#xff0c;arm操作物理地址&#xff0c;驱动操作虚拟地址 2. Linux操作系统的层次 应用层…

SOCKS代理是如何提高网络性能和兼容性的?

SOCKS代理作为一种网络协议中间件&#xff0c;不仅在提升网络隐私和安全性方面发挥着重要作用&#xff0c;也在提高网络性能和兼容性方面有着不容忽视的影响&#x1f680;。本文将深入探讨SOCKS代理如何通过减少网络延迟&#x1f680;、优化数据传输&#x1f504;、提高跨平台兼…

基于Yolov5的检测系统实战

文章目录 一、数据集 二、网络结构 三、完整文件目录介绍 四、测试分析 一、数据集 1、数据格式&#xff1a;图像数据&#xff08;JPG格式&#xff09;&#xff0c;采用labelme标注后的图像&#xff08;XML格式&#xff09;&#xff0c;训练需要的TXT格式 2、数据来源&…

软考高项总结:第17章干系人管理

一、管理基础 1、每个项目都有干系人,他们会受到项目积极或消极的影响,或者能对项目施加积极或消极的影响。项目经理和团队管理干系人的能力决定着项目的成败。为提高项目成功的概率,尽早开始识别干系人并引导干系人参与。当项目章程被批准、项目经理被委任,以及团队开始组…

损失函数-交叉熵 梯度下降

文章目录 1、交叉熵的简单例子1.2、Classification Error&#xff08;分类错误率&#xff09;1.3、Mean Squared Error (均方误差)1.4、交叉熵损失函数1.5、二分类 2、什么是梯度下降法&#xff1f;2.2、梯度下降法的运行过程2.3、二元函数的梯度下降 1、交叉熵的简单例子 参考…

论大数据服务化发展史

文章目录 引言正文单一指令阶段脚本化阶段用户界面操作阶段大模型AIOPS阶段总结 引言 一直想写一篇服务化相关的文章&#xff0c;那就别犹豫了现在就开始吧 正文 作为大数据基础架构工程师&#xff0c;业界也笑称“运维Boy”&#xff0c;日常工作就是在各个机器上部署以及维…

分布式锁-redission

5、分布式锁-redission 5.1 分布式锁-redission功能介绍 基于setnx实现的分布式锁存在下面的问题&#xff1a; 重入问题&#xff1a;重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中&#xff0c;可重入锁的意义在于防止死锁&#xff0c;比如HashTable这样的代码…

python基础——MySQL

文章目录 一、引入pymysql二、使用三、执行非查询性质的SQL语句四、执行查询性质的SQL语句五、数据插入 一、引入pymysql 除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行SQL从而操作数据库。 在Python中&#xff0c;使用第三方库:pymysql来完成对MySQL数据库…

【知识扫盲】DHCP Server扫盲与作用

DHCP Server在实际应用中非常广泛&#xff0c;它适用于各种规模的网络环境&#xff0c;从小型办公室到大型企业网络&#xff0c;都能发挥重要作用。以下是一些具体的使用场景&#xff0c;用通俗易懂的语言进行解释。 1. 办公室网络环境 在一家公司的办公室里&#xff0c;通常会…

【机器学习算法】决策树和随机森林在计算机视觉中的应用

前言 决策树和随机森林在计算机视觉中有着广泛的应用。决策树作为一种简单而强大的分类模型&#xff0c;可以用于图像分类、目标检测、特征提取等任务。它能够根据图像的特征逐层进行判断和分类&#xff0c;从而实现对图像数据的智能分析和理解。随机森林作为一种集成学习方法&…

如何在Ubuntu系统使用docker部署DbGate容器并发布至公网可访问

文章目录 1. 安装Docker2. 使用Docker拉取DbGate镜像3. 创建并启动DbGate容器4. 本地连接测试5. 公网远程访问本地DbGate容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 本文主要介绍如何在Linux Ubuntu系统中使用Docker部署DbGate数据库管理工…

算法——链表(1)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享链表专题的第一部分 如果有不足的或者错误的请您指出! 1.链表常用技巧总结 1.1引入虚拟头结点 在力扣上,基本提供的链表题目都是"无头的",但是针对无头链表,我们最…

使用Android完成案例教学

目录 题目&#xff1a;完成在Android平台下2个玩家分别利用2个手机连接在同一局域网下通过滑动摇杆分别使红飞机和黄飞机移动的开发。&#xff08;全代码解析&#xff09; 题目&#xff1a;完成在Android平台下2个玩家分别利用2个手机连接在同一局域网下通过滑动摇杆分别使红飞…