QCustomplot使用分享(七) 层(完结)

您所在的位置:网站首页 QCustomPlot图例置底层 QCustomplot使用分享(七) 层(完结)

QCustomplot使用分享(七) 层(完结)

2024-07-17 22:16:57| 来源: 网络整理| 查看: 265

一、分层绘制

    一直说要讲2.0.0版本,但总是想把1.3.2版本拿出来比较一下,这篇文章也不例外。QCustomPlot2.0.0beta版本比1.3.2release版本有一个很大的改进那就是分层绘制,所谓分层绘制就是把一张图分几张图来绘制,最后在把这分开的几张图统一绘制到一张图上,比如一张图A,需要分开成3张图B、C和D来绘制,当图A需要重新绘制时,我们一次判断B、C和D是否需要重新绘制,如果不需要绘制的我们直接把图贴到A上,那就很大的减少了重新绘制的时间,而这部分时间其实是没有必要花费的。

二、QCustomPlot的层

    QCustomPlot默认提供了6个层,如下代码所示,分别是:背景层、网格层、主层、坐标轴层、图例层和矩形选择区域层。

1 mLayers.append(new QCPLayer(this, QLatin1String("background"))); 2 mLayers.append(new QCPLayer(this, QLatin1String("grid"))); 3 mLayers.append(new QCPLayer(this, QLatin1String("main"))); 4 mLayers.append(new QCPLayer(this, QLatin1String("axes"))); 5 mLayers.append(new QCPLayer(this, QLatin1String("legend"))); 6 mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); 背景层:绘制背景图 网格层:绘制网格线,每一个坐标轴对应一个网格对象 主层:绘制图表 坐标轴层:绘制坐标轴 图例层:绘制图例 overlay层:绘制最上层的东西,这一层在1.3.2版本时没有。鼠标选择矩形框在此层绘制。可以参考QCustomplot使用分享(五) 布局文章中图1

    实现分层绘制的关键类QCPAbstractPaintBuffer,这是一个抽象基类,通过该类可以拿到一个QCPPainter指针,然后绘制东西的时候,都会绘制在这个指针所指的绘图设备上。QCPAbstractPaintBuffer类一共有3个子类,分别是QCPPaintBufferPixmap、QCPPaintBufferGlPbuffer和QCPPaintBufferGlFbo,这3个类分别使用了不同绘图技术来实现分层绘制。默认使用的是QCPPaintBufferPixmap来绘制,如果想使用QCPPaintBufferGlPbuffer或者QCPPaintBufferGlFbo来绘制,首先要使用setOpenGl接口打开使用opengl开关,然后定义QCP_OPENGL_FBO宏来默认使用QCPPaintBufferGlFbo绘制,或者定义QCP_OPENGL_PBUFFER宏来让默认使用QCPPaintBufferGlPbuffer方式绘制

三、QCPLayer

    下图所示是QCPLayer图层类的部分头文件,代码里的大多数成员变量和成员方法我都给出了注释,大家看看并仔细揣摩一下,应该就基本能理解了。

1 class QCP_LIB_DECL QCPLayer : public QObject 2 { 3 enum LayerMode {//分层绘制原理 4 lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. 5 , lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). 6 }; 7 8 QCPLayer(QCustomPlot* parentPlot, const QString &layerName); 9 virtual ~QCPLayer(); 10 11 // setters: 12 void setVisible(bool visible);//设置层是否可见 13 void setMode(LayerMode mode);//绘制时,painter使用模式 14 15 // non-virtual methods: 16 void replot();//重新绘制层 17 18 protected: 19 QCustomPlot *mParentPlot;//所在图表 20 QString mName;//层名称 21 int mIndex;//层序,决定绘制先后顺序 22 QList mChildren;//层中所有元素 23 bool mVisible;//是否可见标记 24 LayerMode mMode;//绘制模式标记 25 26 // non-property members: 27 QWeakPointer mPaintBuffer;//绘制缓冲区 28 29 // non-virtual methods: 30 void draw(QCPPainter *painter);//使用painter绘制 31 void drawToPaintBuffer();//绘制到缓冲区 32 void addChild(QCPLayerable *layerable, bool prepend);//新增元素 33 void removeChild(QCPLayerable *layerable);//移除元素 34 }; 四、自定义层

    如图1中所示的黑色十字线,就是我在自定义层中绘制的,下面我将我实现的代码贴出来

图1

    实现头文件

1 class CrossLinePlot : public QCPLayerable 2 { 3 Q_OBJECT 4 signals : 5 void DrawCrossLine(const QPoint & pos); 6 7 public: 8 CrossLinePlot(PlotCallback * basePlot, QCustomPlot * plot); 9 ~CrossLinePlot(); 10 11 public: 12 QString LayerName() const;//层名称 13 void SetVisible(bool visible);//设置层是否绘制 14 15 void SetPen(const QPen & pen);/设置十字线画笔 16 17 bool MouseButtonDown() const ; 18 bool GetLineVisible(QCP::LineState line) const; 19 void SetLineShow(QCP::LineState lines);//设置线是否显示 20 21 //十字线同步注册接口 22 bool RegisiterBortherLine(CrossLinePlot * line); 23 bool UnregisiterBortherLine(CrossLinePlot * line); 24 25 protected: 26 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const{}; 27 virtual void draw(QCPPainter * painter); 28 29 private: 30 void DrawLine(QCPAxis * axis, Qt::Orientation orientation);//画指定方向的坐标轴十字线(严格来说应该是一部分,一条线) 31 void SyncLinePosition(const QPoint & pos, double x);//同步线位置 32 33 private slots: 34 void MouseMoveHandle(QMouseEvent * event); 35 36 private: 37 QScopedPointer d_ptr; 38 static std::vector m_BrotherLine;//同步其他十字线 39 };

    实现文件

1 std::vectorCrossLinePlot::m_BrotherLine; 2 3 struct CrossLinePlotPrivate 4 { 5 QCP::LineStates m_bIsVisible; 6 bool m_bLeftButtonPress = false; 7 double m_dAxisXValue = -1; 8 QPoint m_MousePoint; 9 QCPPainter * m_pPainter = nullptr; 10 QPen m_Pen = QPen(Qt::black, 1, Qt::DashDotLine); 11 PlotCallback * m_pParentPlot = nullptr; 12 }; 13 14 CrossLinePlot::CrossLinePlot(PlotCallback * basePlot, QCustomPlot * plot) 15 : QCPLayerable(plot) 16 , d_ptr(new CrossLinePlotPrivate) 17 { 18 d_ptr->m_pParentPlot = basePlot; 19 mParentPlot->addLayer(LayerName()); 20 21 setLayer(LayerName()); 22 23 connect(mParentPlot, &QCustomPlot::mousePress, this, [this](QMouseEvent * event){ 24 if (event->button() & Qt::LeftButton) 25 { 26 d_ptr->m_bLeftButtonPress = true; 27 } 28 }); 29 connect(mParentPlot, &QCustomPlot::mouseRelease, this, [this](QMouseEvent * event){ 30 if (event->button() & Qt::LeftButton) 31 { 32 d_ptr->m_bLeftButtonPress = false; 33 } 34 }); 35 connect(mParentPlot, &QCustomPlot::mouseMove, this, &CrossLinePlot::MouseMoveHandle); 36 37 QVector dashes; 38 qreal space = 4; 39 dashes layer(LayerName()); 56 if (layer) 57 { 58 layer->setVisible(visible); 59 } 60 } 61 62 void CrossLinePlot::SetPen(const QPen & pen) 63 { 64 d_ptr->m_Pen = pen; 65 } 66 67 bool CrossLinePlot::MouseButtonDown() const 68 { 69 return d_ptr->m_bLeftButtonPress; 70 } 71 72 bool CrossLinePlot::GetLineVisible(QCP::LineState line) const 73 { 74 switch (line) 75 { 76 case Qt::Horizontal: 77 return d_ptr->m_bIsVisible.testFlag(QCP::E_Horizontal); 78 break; 79 case Qt::Vertical: 80 return d_ptr->m_bIsVisible.testFlag(QCP::E_Vertical); 81 break; 82 } 83 84 return false; 85 } 86 87 void CrossLinePlot::SetLineShow(QCP::LineState lines) 88 { 89 switch (lines) 90 { 91 case QCP::E_NULL: 92 d_ptr->m_bIsVisible = QCP::E_NULL; 93 break; 94 case QCP::E_Horizontal: 95 d_ptr->m_bIsVisible = QCP::E_Horizontal; 96 break; 97 case QCP::E_Vertical: 98 d_ptr->m_bIsVisible = QCP::E_Vertical; 99 break; 100 case QCP::E_ALL: 101 d_ptr->m_bIsVisible = QCP::E_ALL; 102 break; 103 } 104 105 if (QCPLayer * layer = mParentPlot->layer(LayerName())) 106 { 107 layer->replot(); 108 } 109 110 if (d_ptr->m_bIsVisible == QCP::E_NULL) 111 { 112 for (CrossLinePlot * crossline : CrossLinePlot::m_BrotherLine) 113 { 114 if (crossline != this) 115 { 116 crossline->SyncLinePosition(QPoint(), d_ptr->m_dAxisXValue); 117 } 118 } 119 } 120 } View Code

    有兴趣的同学可以自行看实现文件,代码都不难理解

五、相关文章

  QCustomplot使用分享(一) 能做什么事

  QCustomplot使用分享(二) 源码解读

  QCustomplot使用分享(三) 图

  QCustomplot使用分享(四) QCPAbstractItem

  QCustomplot使用分享(五) 布局

  QCustomplot使用分享(六) 坐标轴和网格线

六、总结

    这是QCustomPlot的第7篇文章了,按照我第二篇文章描述的那样,从QCustomplot使用分享(二) 源码解读、QCustomplot使用分享(三) 图   折线、参数曲线、蜡烛图、柱状图、面积图、QCustomplot使用分享(四) QCPAbstractItem、QCustomplot使用分享(五) 布局、QCustomplot使用分享(六) 坐标轴  网格线和QCustomplot使用分享(七) 层等这几个方面对QCustomPlot做了一个分析,其实还有很多细节我没有说到的地方。

    虽然我使用QCustomPlot库的时间不长,但是用了3天的时间我把QCustomPlot的使用或者说是心得记录了下来,这几篇文章在写的过程中,也是自我回忆、自我重新理解的一个过程,说实话写完这几篇文章我还是收获挺大的,最起码能连贯的把这个源码库融合起来,现在在回想起这个库我就会觉得脑子里已经有了一个大概的图,也可以说是一幅画,基本的功能模块大体掌握,如果这时候给我一个需求,那我可能会更好的理解这个需求,更好的去在合适的地方更合理的完成这个需求。

七、示例下载

  基于QCustomPlot1.3.2的二次开发

  基于QCustomPlot2.0.0的二次开发

 

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!   

  

很重要--转载声明

本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。  奋斗中的无名小卒。。。


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭