QCustomPlot系列(7)-鼠标跟随显示坐标值(也即:十字游标功能)游标可以吸附采样点

先来个动图看看效果:

 

这个动图中实现的功能有:1、十字线游标的X值跟随鼠标,Y值不跟随。2、游标的Y值跟随鼠标的X值对应的曲线的Y值,可以点击图例,更换游标跟随哪个曲线的Y值,3、游标不会出现在曲线中不存在点上,而是自动吸附到距离鼠标最近的曲线上的点。

 

 

在QCustomPlot插入游标、绿色文本框,都很简单,可参考我的另一篇博客《QCustomPlot系列(6)-》。

现在的问题有这些:

1、如何让插入的游标只跟随鼠标的X值,不跟随Y值?

2、如何让绿色文本框跟着游标动?

3、如何禁止游标出现在曲线中不存在点上?

 

 

在此之前先设置一下游标样式:
 

tracer->setPen(QPen(Qt::DashLine));//游标线型:虚线
tracer->setStyle(QCPItemTracer::tsPlus);//游标样式:十字星、圆圈、方框等

游标跟随鼠标的X值移动,只需覆盖QCustomplot的鼠标移动事件就好了:

void MultiCurvesPlot::mouseMoveEvent(QMouseEvent *event)
{
    QCustomPlot::mouseMoveEvent(event);//避免让父类的移动事件失效

    if(tracerEnable)//游标使能
    {
        if(getGraphs().contains(traceGraph))//检查一下游标附着的graph是否还存在
        {
            double x = xAxis->pixelToCoord(event->pos().x());//鼠标点的像素坐标转plot坐标
            tracer->setGraph(traceGraph);//设置游标吸附在traceGraph这条曲线上
            tracer->setGraphKey(x);//设置游标的X值(这就是游标随动的关键代码)
            double traceX = tracer->position->key();
            double traceY = tracer->position->value();

            tracerXText->setText(QDateTime::fromMSecsSinceEpoch(traceX * 1000.0).toString("hh:mm:ss.zzz"));//游标文本框,指示游标的X值
            tracerYText->setText(QString::number(traceY));//游标文本框,指示游标的Y值

            //计算游标X值对应的所有曲线的Y值
            for(int i = 0; i < graphCount(); i++)
            {
                //搜索左边离traceX最近的key对应的点,详情参考findBegin函数的帮助
                QCPDataContainer::const_iterator coorPoint = graph(i)->data().data()->findBegin(traceX, , true);//true代表向左搜索
                qDebug() << QString("graph%1对应的Y值是").arg(i) << coorPoint->value;

            }
        }
    }
}

 

上面有几个函数是我自己写的,不是QCustomplot自带的,稍微解释一下上述代码:
getGraphs()是获取当前plot中所有的graph列表,实际上QCustomplot类中有个private变量在维护这个QList,这个函数把这个List给传出来了。
traceGraph是记录此刻游标与哪个graph关联。点击图例中的曲线名称,可以修改traceGraph。

还有一个小问题就是,当鼠标点的位置并没有曲线中的X与之完全相等时,要把游标强制显示到采样点出处,如下图所示。

由下图可见,游标并没有完全跟随鼠标的X值,而是被采样点给吸过去了。

QCustomPlot系列(7)-鼠标跟随显示坐标值(也即:十字游标功能)游标可以吸附采样点_第1张图片

实现这一功能也很简单,这是QCustomplot自带的功能,只需在游标初始化时,设置:
tracer->setInterpolating(false);//游标禁用插值
一旦设置了禁用插值属性,当设置游标位置时(也即tracer->setGraphKey(x);),setGraphKey(x)函数所设置的标志位会导致游标的位置更新函数QCPItemTracer::updatePosition()中会自动搜索一个距离形参x最近的采样点的x,作为游标的x值,这样就实现了“采样点捕捉游标”的功能,也即:游标的X值总是永远等于某个采样点的X值!

 

最后一个问题,当plot中有多条曲线(graph)时,我们希望能够看到当前游标X对应的所有的曲线的Y值,这个功能该怎么写?

原理步骤是这样的:

(1)拿到被游标处理过(被采样点捕捉后的游标)的横轴坐标double traceX。
(2)遍历曲线(graph),利用graph(i)->data().data()->findBegin(traceX, true)来计算graph(i)曲线中距离traceX最近的采样点,
findBegin的第二个参数为true,true代表搜出的最近的采样点在traceX的左边,false代表在右边。

你可能感兴趣的:(QT,QT/QCustomPlot)