QcustomPlot 多条单条曲线光标自动更随的实现

QcustomPlot 多条单条曲线光标自动更随的实现QcustomPlot光标跟随最近有一个需求是能绘制多条曲线且能光标跟随,上网搜了很多相关的资料,如下边这个博客中查到了鼠标更随的相关代码,他的图如下所示——[原文链接地址](https://blog.csdn.net/sunnyloves/article/details/82344815)还有一篇如下所示——[原文链接地址](https://www.cnblogs.com…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

QcustomPlot光标跟随

最近有一个需求是能绘制多条曲线且能光标跟随,上网搜了很多相关的资料,如下边这个博客中查到了鼠标更随的相关代码,他的图如下所示——原文链接


QcustomPlot 多条单条曲线光标自动更随的实现

还有一篇如下所示——原文链接


QcustomPlot 多条单条曲线光标自动更随的实现

第一篇博主的实现方法其实已经比较完善了但是我按照他的方法去做后构造函数有点问题,所以对其做了一些修改之后得到如下结果——


QcustomPlot 多条单条曲线光标自动更随的实现
三条每条100万数据点曲线实时追踪无延迟,边界跳0无数据,本文所用为QcustomPlot2.0.1。 首先说的是对上边所提第一篇博客做的修改,代码如下

#ifndef MYTRACER_H
#define MYTRACER_H

#include <QObject>
#include "qcustomplot.h"
enum TracerType
{ 
   
    XAxisTracer,
    YAxisTracer,
    DataTracer
};

class myTracer : public QObject
{ 
   
    Q_OBJECT
public:



public:
    explicit myTracer(QCustomPlot *_plot,QCPGraph *_graph, TracerType _type);//这里与原贴不同,按照原贴构造总是过不去
    ~myTracer();

    void setPen(const QPen &pen);
    void setBrush(const QBrush &brush);
    void setText(const QString &text);
    void setLabelPen(const QPen &pen);
    void updatePosition(double xValue, double yValue);

protected:
    void setVisible(bool visible);
protected:
    QCustomPlot *plot ;	     //传入实例化的QcustomPlot
    QCPGraph *graph;	   	 //这里是存传入的绘图图层
    QCPItemTracer *tracer;   // 跟踪的点
    QCPItemText *label;   	 // 显示的数值
    QCPItemLine *arrow;  	 // 箭头

    TracerType type;
    bool visible;

signals:

public slots:

};

#endif // MYTRACER_H
#include "mytracer.h"
myTracer::myTracer(QCustomPlot *_plot, QCPGraph *_graph, TracerType _type) : plot(_plot),
graph(_graph),
type(_type),
visible(false)
{ 

if (plot)
{ 

tracer = new QCPItemTracer(plot);
tracer->setStyle(QCPItemTracer::tsPlus);//可以选择设置追踪光标的样式,这个是小十字,还有大十字,圆点等样式
// tracer->setPen(QPen(Qt::red));
tracer->setPen(graph->pen());//设置tracer的颜色
tracer->setBrush(graph->pen().color());
tracer->setSize(10);
label = new QCPItemText(plot);
label->setLayer("overlay");
label->setClipToAxisRect(false);
label->setPadding(QMargins(5, 5, 5, 5));
label->position->setParentAnchor(tracer->position);
label->setFont(QFont("宋体", 10));
arrow = new QCPItemLine(plot);
arrow->setLayer("overlay");
arrow->setPen(graph->pen());//设置箭头的颜色
arrow->setClipToAxisRect(false);
arrow->setHead(QCPLineEnding::esSpikeArrow);
switch (type) { 

case XAxisTracer:
{ 

tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
tracer->position->setTypeY(QCPItemPosition::ptAxisRectRatio);
label->setBrush(QBrush(QColor(244, 244, 244, 100)));
label->setPen(QPen(Qt::black));
label->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
arrow->end->setParentAnchor(tracer->position);
arrow->start->setParentAnchor(arrow->end);
arrow->start->setCoords(20, 0);//偏移量
break;
}
case YAxisTracer:
{ 

tracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio);
tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
label->setBrush(QBrush(QColor(244, 244, 244, 100)));
label->setPen(QPen(Qt::black));
label->setPositionAlignment(Qt::AlignRight|Qt::AlignHCenter);
arrow->end->setParentAnchor(tracer->position);
arrow->start->setParentAnchor(label->position);
arrow->start->setCoords(-20, 0);//偏移量
break;
}
case DataTracer:
{ 

tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
label->setBrush(QBrush(QColor(244, 244, 244, 150)));
label->setPen(graph->pen());
label->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter);
arrow->end->setParentAnchor(tracer->position);
arrow->start->setParentAnchor(arrow->end);
arrow->start->setCoords(25, 0);
break;
}
default:
break;
}
setVisible(false);
}
}
myTracer::~myTracer()
{ 

if (tracer)
plot->removeItem(tracer);
if (label)
plot->removeItem(label);
}
void myTracer::setPen(const QPen &pen)
{ 

tracer->setPen(pen);
arrow->setPen(pen);
}
void myTracer::setBrush(const QBrush &brush)
{ 

tracer->setBrush(brush);
}
void myTracer::setLabelPen(const QPen &pen)
{ 

label->setPen(pen);
}
void myTracer::setText(const QString &text)
{ 

label->setText(text);
}
void myTracer::setVisible(bool visible)
{ 

tracer->setVisible(visible);
label->setVisible(visible);
arrow->setVisible(visible);
}
void myTracer::updatePosition(double xValue, double yValue)
{ 

if (!visible)
{ 

setVisible(true);
visible = true;
}
if (yValue > plot->yAxis->range().upper)
yValue = plot->yAxis->range().upper;
switch (type) { 

case XAxisTracer:
{ 

tracer->position->setCoords(xValue, 1);
label->position->setCoords(0, 15);
arrow->start->setCoords(0, 15);
arrow->end->setCoords(0, 0);
break;
}
case YAxisTracer:
{ 

tracer->position->setCoords(1, yValue);
label->position->setCoords(-20, 0);
break;
}
case DataTracer:
{ 

tracer->position->setCoords(xValue, yValue);
label->position->setCoords(25, 0);
break;
}
default:
break;
}
}

附上我的实现主函数

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <string>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ 

ui->setupUi(this);
m_Plot = QSharedPointer<QCustomPlot> (new QCustomPlot());
ui->verticalLayout->addWidget(m_Plot.data());
//设置基本坐标轴(左侧Y轴和下方X轴)可拖动、可缩放、曲线可选、legend可选、设置伸缩比例,使所有图例可见
m_Plot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes
|QCP::iSelectLegend | QCP::iSelectPlottables);
m_Plot->legend->setVisible(true);
m_Plot->legend->setFont(QFont("Helvetica",9));
m_Plot->legend->setBrush(QColor(255,255,255,100));
// generate some data:
QVector<double> x(1000001), y(1000001), y1(1000001), y2(1000001);
for (int i=0; i<1000001; ++i)
{ 

x[i] = i;
y[i] = x[i]/50000 * x[i]/50000;
y1[i] = y[i] * 1.2;
y2[i] = y[i] * 1.4;
}
QVector<QVector<double> > vec;
vec.push_back(x);
vec.push_back(y);
m_value.push_back(vec);
QVector<QVector<double> >().swap(vec);
vec.push_back(x);
vec.push_back(y1);
m_value.push_back(vec);
QVector<QVector<double> >().swap(vec);
vec.push_back(x);
vec.push_back(y2);
m_value.push_back(vec);
QVector<QVector<double> >().swap(vec);
StaticDataPlot(m_value);
m_Plot->xAxis->rescale(true);
m_Plot->axisRect()->axis(QCPAxis::atBottom, 0)->setPadding(10); // add some padding to have space for tags
m_TraserX = QSharedPointer<myTracer> (new myTracer(m_Plot.data(), m_Plot->graph(0), XAxisTracer));
connect(m_Plot.data(), SIGNAL(mouseMove(QMouseEvent*)), this,SLOT(showTracer(QMouseEvent*)));
m_Plot->replot();
}
MainWindow::~MainWindow()
{ 

delete ui;
}
void MainWindow::showTracer(QMouseEvent *event)
{ 

double x = m_Plot->xAxis->pixelToCoord(event->pos().x());
m_TraserX->updatePosition(x, 0);
m_TraserX->setText(QString::number(x, 'f', 2));
for(int i=0;i<m_Graph.size();i++)
{ 

double y = 0;
QSharedPointer<QCPGraphDataContainer> tmpContainer;
tmpContainer = m_Graph[i]->data();
//使用二分法快速查找所在点数据!!!敲黑板,下边这段是重点
int low = 0, high = tmpContainer->size();
while(high > low)
{ 

int middle = (low + high) / 2;
if(x < tmpContainer->constBegin()->mainKey() ||
x > (tmpContainer->constEnd()-1)->mainKey())
break;
if(x == (tmpContainer->constBegin() + middle)->mainKey())
{ 

y = (tmpContainer->constBegin() + middle)->mainValue();
break;
}
if(x > (tmpContainer->constBegin() + middle)->mainKey())
{ 

low = middle;
}
else if(x < (tmpContainer->constBegin() + middle)->mainKey())
{ 

high = middle;
}
if(high - low <= 1)
{ 
   //差值计算所在位置数据
y = (tmpContainer->constBegin()+low)->mainValue() + ( (x - (tmpContainer->constBegin() + low)->mainKey()) *
((tmpContainer->constBegin()+high)->mainValue() - (tmpContainer->constBegin()+low)->mainValue()) ) /
((tmpContainer->constBegin()+high)->mainKey() - (tmpContainer->constBegin()+low)->mainKey());
break;
}
}
m_Tracer[i]->updatePosition(x, y);
m_Tracer[i]->setText(QString::number(y, 'f', 2));
}
m_Plot->replot();
}

介于很多小伙伴找我咨询代码问题,找到之前面目全非的代码重新修改编译了一下,可能有一点小不同但是效果相同,小手点下关注再去下载哦~
CustomPlotTest.zip

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/181226.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • wordpress被挂马_php绕过

    wordpress被挂马_php绕过注:本文仅供学习参考网页挂马简介网页挂马指的是把一个木马程序上传到一个网站里面,然后用木马生成器生成一个网马,放到网页空间里面,再加代码使得木马在打开网页时运行。网页挂马工作原理作为网页挂马的散布者,其目的是将木马下载到用户本地并进一步执行,当木马得到执行后,就意味着会有更多的木马被下载,且进一步被执行。这样就进入一个恶性的循环,从而使用户的电脑遭到攻击和控制。为达到目的首先要将木马下载到本地。常…

  • python贪吃蛇最简单代码_用python写贪吃蛇

    python贪吃蛇最简单代码_用python写贪吃蛇一、前言之前版本很多小伙伴都觉得难度过高,另外也有粉丝问还能不能精简代码。所以这版降低了难度(由原来过关增加5km/h改为3.5KM/h),并通过反射代替IFELSE的写法,并删除了一些冗余的代码,将代码压缩到了71行(不必要的压缩代码是不建议的,这里压缩代码只是为了好玩)二、实现效果三、环境要求python3+pygame包安装命令:打开cmd输入:pipinstallpygame四、源码分享importpygameimportsysimportra

  • 三星ODIN刷机包的修改

    三星ODIN刷机包的修改SunnyOK系列讲座索引【第一讲】如何用Odin刷机-新手必读http://bbs.gfan.com/android-1653492-1-1.html【第二讲】I897卡刷或CWM刷机教程http://bbs.gfan.com/android-1701867-1-1.html【第三讲】APK应用程序的解包、修改、编辑、打包及应用http://bbs

  • C#操作XML的完整例子——XmlDocument篇「建议收藏」

    C#操作XML的完整例子——XmlDocument篇「建议收藏」这是一个用c#控制台程序下, 用XmlDocument进行XML操作的的例子,包含了查询、增加、修改、删除、保存的基本操作。较完整的描述了一个XML的整个操作流程。适合刚入门.netXML操作的朋友参考和学习。假设有XML文件:books.xmlxml version=”1.0″ encoding=”UTF-8″?>books> book>  name>哈里波特name>  pr

  • window安装maven配置环境变量[通俗易懂]

    window安装maven配置环境变量[通俗易懂]首先去maven官网下载,点击这里去下载页面,下拉选择下图点击下载下载好之后解压出来,然后配置环境变量,在我的电脑-右键-属性-高级系统设置-环境变量然后在系统变量下点击新建变量名:M2_HOME变量值:你下载的maven解压出来的路径,我的如下,复制路径粘贴到变量值里,点击确定再找到系统变量里的:Path在变量值里加入:%M2_HOME%/bin不要…

  • Java事务详解[通俗易懂]

    Java事务详解[通俗易懂]1.什么是JAVA事务?通常的观念认为,事务仅与数据库相关。事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写。事务的原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。事务的一致性:表示当事务执行失败时,所有被该事务影响的数据…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号