一.效果图
效果图如下:
二.具体功能
具体功能如下:
- 显示动态曲线及图例
- 图例文本颜色与其对应的曲线一致
- 右侧显示实时数据,数据点以圆点样式显示,实时数据显示无文本框
- 曲线数值跟踪,当鼠标移动时,显示鼠标所在点的所有曲线的y值
- 曲线图的缩放和平移
关键的点在代码中都有注释,正文就不再赘述。本功能基于QCustomplot v2.0.1版本实现,QCustomplot的使用很简单,从官网下载后,解压,将qcustomplot.h好qcustomplot.cpp拷贝到自己的project目录下,并加入到项目中即可。
需要在.pro文件中添加如下内容:
QT += printsupport
三.代码结构
代码结构如下图所示:
PlotValueTracer:游标类,用于显示游标和数值
PlotBaseWidget:曲线图窗口,便于直接使用
四.代码
主要代码如下:
PlotValueTracer.h代码
#ifndef PLOTVALUETRACER_H
#define PLOTVALUETRACER_H
#include <QObject>
#include "qcustomplot.h"
//定义追踪样式
enum PlotValueTracerType
{
XAxisTracer,
YAxisTracer,
DataTracer
};
class PlotValueTracer : public QObject
{
Q_OBJECT
public:
explicit PlotValueTracer(QPointer<QCustomPlot> _parentPlot, PlotValueTracerType _type,QCPGraph *_graph = 0);
~PlotValueTracer();
// setters:
void setTracerStyle(QCPItemTracer::TracerStyle e); //设置游标点的样式
void setArrowLineLength(int len); //设置线元素的偏移长度
void setArrowHead(QCPLineEnding::EndingStyle e); //设置线元素头样式
void setArrowPen(const QPen &pen); //设置线元素的画笔
void setTracerPen(const QPen &pen); //设置游标点的画笔
void setLabelPen(const QPen &pen); //设置文本元素的画笔
void setTracerBrush(const QBrush &brush); //设置游标点的画刷
void setLabelBrush(const QBrush &brush); //设置文本元素画刷
void setText(const QString &text); //设置文本元素文本
void setTextColor(QColor &c); //设置文本元素中文本的颜色
void setTextMargin(QMargins mar); //设置文本元素边界
void setVisible(bool visible); //设置游标的显示/隐藏
void updateTracerPosition(double x,double y); //更新游标位置
private:
void updatePositionX(double value); //XAxisTracer显示模式,更新游标位置
void updatePositionY(double value); //YAxisTracer显示模式,更新游标位置
void updatePositionData(double xValue, double yValue); //DataTracer显示模式,更新游标位置
private:
QPointer<QCustomPlot> m_parentPlot; //曲线图
QCPGraph *m_graph; //这里是存传入的绘图图层
QPointer<QCPItemTracer> m_tracer; //数据跟踪点
QPointer<QCPItemLine> m_arrowLine; //线元素
QPointer<QCPItemText> m_labelText; //数据跟踪点文本元素
PlotValueTracerType m_type; //追踪点类型
int m_nLineLength; //线元素的长度
};
#endif // PLOTVALUETRACER_H
PlotValueTracer.cpp代码
#include "PlotValueTracer.h"
PlotValueTracer::PlotValueTracer(QPointer<QCustomPlot> _parentPlot,PlotValueTracerType _type,QCPGraph *_graph) :
QObject(_parentPlot),
m_parentPlot(_parentPlot),
m_type(_type),
m_graph(_graph),
m_nLineLength(15)
{
//游标点
m_tracer = new QCPItemTracer(m_parentPlot);
if(m_graph)
{
m_tracer->setPen(m_graph->pen());
m_tracer->setBrush(m_graph->brush());
}
//线元素
m_arrowLine = new QCPItemLine(m_parentPlot);
m_arrowLine->setLayer("overlay");
m_arrowLine->setClipToAxisRect(false);
if(m_graph)
m_arrowLine->setPen(m_graph->pen());//设置箭头的颜色
m_arrowLine->setHead(QCPLineEnding::esSpikeArrow);
//文本元素
m_labelText = new QCPItemText(m_parentPlot);
m_labelText->setLayer("overlay");
m_labelText->setClipToAxisRect(false);
m_labelText->setPadding(QMargins(3, 4, 3, 4));
if(m_graph)
m_labelText->setPen(m_graph->pen());
m_labelText->position->setParentAnchor(m_tracer->position);//m_arrowLine->start);
switch(m_type)
{
case XAxisTracer:
m_tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
m_tracer->position->setTypeY(QCPItemPosition::ptAxisRectRatio);
m_arrowLine->end->setParentAnchor(m_tracer->position);
m_arrowLine->start->setParentAnchor(m_arrowLine->end);
m_arrowLine->start->setCoords(m_nLineLength, 0);//偏移量,用于设置线元素的长度
m_labelText->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
break;
case YAxisTracer:
m_tracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio);
m_tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
m_tracer->position->setCoords(1, 0); //这一句必不可少
m_arrowLine->end->setParentAnchor(m_tracer->position);
m_arrowLine->start->setParentAnchor(m_arrowLine->end);//m_labelText->position m_arrowLine->end
m_arrowLine->start->setCoords(m_nLineLength, 0);//偏移量,用于设置线元素的长度
m_labelText->setPositionAlignment(Qt::AlignTop|Qt::AlignVCenter);
break;
case DataTracer:
m_tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
m_tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
m_arrowLine->end->setParentAnchor(m_tracer->position);
m_arrowLine->start->setParentAnchor(m_arrowLine->end);
m_arrowLine->start->setCoords(m_nLineLength, 0);//偏移量,用于设置线元素的长度
m_labelText->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter);