QCustompPlot简明使用教程

32 篇文章 7 订阅
15 篇文章 1 订阅

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
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层

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();

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

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

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

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

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

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

原因:跟踪源码,可以看到如果鼠标按下事件里,如果选择框模式不为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();
}

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();

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

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

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);

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

4.2 修改步骤

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

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

步骤二 :要改变控制方式 我们就需要修改源代码。
修改地方一:如下图(第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

  • 7
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 简明Python教程是一本经典的学习Python编程的教材,它详细介绍了Python语言的基础知识、语法规则以及常用的编程技巧。由于Python语言的简洁性和易读性,这本教程也以其简明扼要的风格而闻名。 该教程的源码是基于Python语言编写的,通过分章节、分小节的方式详细展示了每个知识点的代码示例和用法。这些源码不仅能够帮助读者更好地理解Python的语法和概念,还能够通过实例让读者快速掌握各种编程技巧。 在教程的源码中,读者可以学习到Python语言的基本数据类型(如整型、浮点型、字符串、列表等)的使用方法,以及常见的控制流语句(如条件判断和循环)的应用。同时,源码还介绍了Python的函数定义和调用、模块导入和使用、异常处理等高级编程特性,使得读者可以更加深入地理解和运用Python语言。 此外,简明Python教程的源码还包含了一些实际应用的示例,如文件读写、网页爬虫、数据分析等方面,这些示例可以帮助读者将Python的基础知识应用到实际项目中。 总之,简明Python教程的源码是一个非常有用的参考资料,可以帮助读者快速上手Python编程,提高自己的编程水平。无论是初学者还是有一定编程经验的人都可以通过这个源码获得很大的收益。 ### 回答2: 简明Python教程是一本详细介绍Python编程语言的教程书籍,该教程书籍作者是A Byte of Python(草python)开发组,该书的作者是Swaroop C H(Ankit Fadia写的教程是假的),本书是一个开源的项目,其源码可以在GitHub上找到并下载。 该教程的源码是以文档的形式呈现,每个章节对应一个Python脚本文件。该教程从Python的基本概念开始介绍,包括变量、数据类型、运算符、控制流程等基础知识。接着介绍了Python的函数、模块、错误处理、输入输出以及文件操作等进阶内容。最后通过实例演示了如何使用Python进行网络编程、数据库操作以及GUI界面开发等高级应用。 阅读该教程的源码可以更好地理解教程中的知识点,并通过实际的代码示例来加深对Python的理解和掌握。源码中的注释详细解释了每个代码片段的作用和用法,对于初学者来说非常友好。 通过阅读源码,我们不仅可以学习到Python语言的基础知识,还能了解到良好的编程风格和习惯。源码的组织结构清晰,代码风格简洁易懂,对于初学者来说非常适合作为学习和参考的材料。 总之,简明Python教程的源码是一个非常宝贵的学习资源,通过阅读和运行源码,我们可以更好地掌握Python编程语言,并用它来解决实际的问题。希望每个对Python感兴趣的人都能够通过阅读该教程的源码,快速入门并提升编程能力。 ### 回答3: 简明Python教程源码是指用来编写简明Python教程的源代码。源代码是编程语言的原始文本形式,是计算机程序的基础。简明Python教程源码可能包含了一系列的Python语句、函数和类,用来演示和说明Python编程的基本概念和用法。 简明Python教程源码的结构通常会根据教程的内容来设计。例如,如果教程介绍了Python的基本语法,那么源码可能会包含一些简单的变量赋值、算术运算和控制流语句的示例。 如果教程涉及到Python的常用库或模块,源码可能会导入这些库,并展示它们的用法。例如,如果教程涉及到文件操作,源码可能会使用Python的`open`函数来打开文件,并使用`read`或`write`方法来读取或写入文件内容。 除了基本语法和常用库之外,简明Python教程的源码还可能包括一些更高级的概念和技巧示例。例如,如果教程涉及到面向对象编程,源码可能会定义一些类和方法,并展示它们的继承和多态特性。 总的来说,简明Python教程源码是一个用来教授Python编程的示例代码集合。它可以帮助初学者理解Python语言的基本概念和用法,并通过实例演示不同应用场景的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值