当前位置:   article > 正文

QCustompPlot简明使用教程

qcustom

1. 前言

QCustomPlot 是一个基于Qt的画图和数据可视化C++控件。QCustomPlot 致力于提供美观的界面,高质量的2D画图、图画和图表,同时为实时数据可视化应用提供良好的解决方案。
QCustomPlot是一个小型的Qt画图标类,支持绘制静态曲线、动态曲线、多重坐标曲线,柱状图,蜡烛图等。只需要在项目中加入头文件qcustomplot.h和qcustomplot.cpp文件,然后使一个widget提升为QCustomPlot类,即可使用。

QCustomPlot官网:http://www.qcustomplot.com/
QCustomPlot下载地址: http://www.qcustomplot.com/index.php/download

1.1 简单介绍QCustomPlot的几个重要类

QCustomPlot 图表类:用于图表的显示和交互

QCPLayer 图层:管理图层元素(QCPLayerable),所有可显示的对象都是继承自图层元素
QCPAbstractPlottable 绘图元素:包含 折线图(QCPGraph)、曲线图(QCPCurve)、柱状图(QCPBars)、QCPStatiBox(盒子图)、QCPColorMap(色谱图)、QCPFinancial(金融图)
QCPAxisRect 坐标轴矩形:一个坐标轴矩形默认包含上下左右四个坐标轴,但是可以添加多个坐标轴

简单介绍QCustomPlot类

QCustomPlot类管理着所有的图层,它默认自带了六个图层,分别是:
背景层background
网格层grid
绘图层main
坐标轴层axes
图例层legend
overlay层overlay
依据层的顺序的不同,绘制的顺序也不同,越在底下的层越早绘制,当前层默认为绘图层main

而我们的绘图区域则在QCPAxisRect中,QCustomPlot类默认包含一个QCPAxisRect,我们可以在下图中可以看到一个QCPAxisRect一般来说会有上轴xAxis2、下轴xAxis、左轴yAxis和右轴yAxis2四个轴
在这里插入图片描述

1.2

层和层元素

在QCustomPlot中,一切可显示的对象都是继承自层元素QCPLayerable,层QCPLayer则管理着层元素,QCustomPlot利用层决定了不同元素的绘制顺序
层有两种刷新模式:

lmLogical 只用于渲染的顺序,并且与相邻的lmLogical层共享绘图缓存(注意这里的相邻,如果前一个层是lmBuffered模式,则会新建一个绘图缓存用于绘图)
lmBuffered 层拥有自己的绘图缓存,并且可以单独的刷新(调用QCPLayer::replot函数)
默认只有overlay层启用了lmBuffered单独绘制机制,其它层都共享一个绘图缓存,因为overlay层主要是用于存放悬浮与图表上的item项,需要频繁的刷新,启用了lmBuffered的层会多占用内存

布局和布局元素

在QCustomPlot中,布局方式只有两种:

QCPLayoutGrid 网格布局
QCPLayoutInset 内嵌式布局, 这种布局的作用是把子元素与布局的边界对齐或者将其放置在布局内的任意位置(图例QCPLegend就被放置在此布局内),严格来说这个并不算布局
我们可以看下继承关系图,可以看到这两种布局都继承自QCPLayout,而QCPLayout继承自QCPLayoutElement布局元素,所以一个布局可以包含另一个布局,布局内的元素都要继承自QCPLayoutElement
在这里插入图片描述
在QCustomPlot里面维护着一个网格布局,默认只有一个QCPAxisRect元素,而QCPAxisRect里则维护这一个内嵌式的布局,用于放置图例QCPLegend
Qt工程文件中加入:

QT +=printsupport
  • 1
mPlotLayout = new QCPLayoutGrid;             
mPlotLayout->initializeParentPlot(this);
mPlotLayout->setParent(this);
mPlotLayout->setLayer(QLatin1String("main"));   // 设置网格布局的层为main层

QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true);
mPlotLayout->addElement(0, 0, defaultAxisRect);
xAxis = defaultAxisRect->axis(QCPAxis::atBottom);
yAxis = defaultAxisRect->axis(QCPAxis::atLeft);
xAxis2 = defaultAxisRect->axis(QCPAxis::atTop);
yAxis2 = defaultAxisRect->axis(QCPAxis::atRight);
legend = new QCPLegend;
legend->setVisible(false);                    // 默认不显示图例
defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight | Qt::AlignTop);   // 设置图例对齐于QCPAxisRect的右上角
defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12));                // 设置布局的外边距

defaultAxisRect->setLayer(QLatin1String("background"));                              // QCPAxisRect的层设置为background层
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2 应用

    ui->lineEdit_xRange->setText("0,3");
    ui->lineEdit_yRange->setText("15,35");
    ui->plot->addGraph(); //添加一个曲线图Graph
	
	ui->plot->graph(0)->setData(Dat.time, Dat.sigvalue); //为曲线图添加数据
    QFileInfo fileInfo = QFileInfo(fileName); //短文件名格式
    ui->plot->graph(0)->setName(fileInfo.fileName()); //设置曲线图的名字,短文件名格式
//    ui->plot->graph(0)->setName(fileName); //设置曲线图的名字,长文件名格式
    ui->plot->xAxis->setLabel("xxx"); //设置x轴的标签
    ui->plot->yAxis->setLabel("yyy"); //设置y轴的标签
    ui->plot->xAxis->setRange(0, 3); //设置x轴的范围为0-3mins
    ui->plot->yAxis->setRange(15, 40); //设置y轴的范围
    ui->plot->legend->setVisible(true); //显示图例
    ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); // 设置可以放大缩小、上下左右滑动
    ui->plot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);//模式:框选放大
    ui->plot->replot();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

qcustomPlot是有鼠标选择框功能的,只是默认是不使能,所以平常拖动鼠标没有反应,调用setSelectionRectMode可以开启选框,如下开启:

customPlot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);//模式:框选放大
  • 1

QCP::SelectionRectMode有几个枚举值
在这里插入图片描述
(1)设置选框的边框和颜色

    customPlot->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine));//虚线
    customPlot->selectionRect()->setBrush(QBrush(QColor(0,0,100,50)));//半透明浅蓝
  • 1
  • 2

(2)框选放大和拖动无法同时使用
setSelectionRectMode如果设置为srmZoom放大模式, 即使Interaction设置了拖动iRangeDrag,鼠标按下后依然是框选放大,而不会是拖动曲线,如下代码拖动是无效的:

    customPlot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);//模式:框选放大
    customPlot->setInteraction(QCP::iRangeDrag,true);//使能拖动
  • 1
  • 2

原因:跟踪源码,可以看到如果鼠标按下事件里,如果选择框模式不为srmNone,就执行选框操作了,而不会执行Interaction操作。
在这里插入图片描述
在这里插入图片描述

void MainWindow::on_pBtn_Settings_clicked()
{
    double low,high;
    low = ui->lineEdit_xRange->text().split(',').at(0).toDouble();
    high = ui->lineEdit_xRange->text().split(',').at(1).toDouble();
    if(low < high)
        ui->plot->xAxis->setRange(low,high);
    low = ui->lineEdit_yRange->text().split(',').at(0).toDouble();
    high = ui->lineEdit_yRange->text().split(',').at(1).toDouble();
    if(low < high)
        ui->plot->yAxis->setRange(low,high);
    ui->plot->replot();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3 文件名

获取整个文件名(包含路径)

QString fileFull, fileName, filePath,fileSuffix;
    QFileInfo fileinfo;
    fileFull = QFileDialog::getOpenFileName(this,tr("file"),"/",tr("text(*.txt)"));  //获取整个文件名
    //fileFull = E:\QtCode\newExample\myTry\新建文本文档.txt
    //获取文件信息
    fileinfo = QFileInfo(fileFull);
    //fileinfo = E:\QtCode\newExample\myTry\新建文本文档.txt
    //获取文件名字
    fileName = fileinfo.fileName();
    //fileName = 新建文本文档.txt
    //获取文件后缀
    fileSuffix = fileinfo.suffix();
    //fileSuffix = txt
    //获取文件绝对路径
    filePath = fileinfo.absolutePath();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

获取短文件名(去掉路径)

//获取文件信息
    fileinfo = QFileInfo(fileFull);
    //fileinfo = E:\QtCode\newExample\myTry\新建文本文档.txt
    //获取文件名字
    fileName = fileinfo.fileName();
    //fileName = 新建文本文档.txt
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4 QCustomPlot左键框选放大、右键平移

4.1 左键框选放大

	customPlot->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine));//设置选框的样式:虚线
	customPlot->selectionRect()->setBrush(QBrush(QColor(0,0,100,50)));//设置选框的样式:半透明浅蓝
	customPlot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
  • 1
  • 2
  • 3

不过使用官方的框选放大功能,也带来一个毛病,就是鼠标左、右、中,三个键都变成了框选放大,失去了拖拽平移功能,这用起来很不爽,我们改一下官方源码。

4.2 修改步骤

步骤一: 我们知道 setInteractions函数API是实现拽轴的范围、滚动缩放轴的范围,左键点选图层的功能 我们进入源代码找到这个函数就可以了(还不知道setInteractions函数的 可以我前面一篇),我们这把它限制在右键按下的前提下,

 // 支持鼠标拖拽轴的范围、滚动缩放轴的范围,左键点选图层(每条曲线独占一个图层)
	customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

  • 1
  • 2
  • 3

步骤二 :要改变控制方式 我们就需要修改源代码。
修改地方一:如下图(第15564和15568行)
在这里插入图片描述

修改地方二:如下图 (第18527行)
在这里插入图片描述
在这里插入图片描述

参考资料:https://www.jianshu.com/p/cfc2637ef3c4
http://www.qtcn.org/bbs/read-htm-tid-88422.html
https://blog.csdn.net/yxy244/article/details/100547688
https://blog.csdn.net/weixin_39328406/article/details/111998423

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/297478
推荐阅读
相关标签
  

闽ICP备14008679号