QCustomPlot基础教程(六)——Qt设置鼠标跟随动态显示曲线上的点的值

一、代码示例

1.1 基本设置

首先新建一个widget文件,UI界面内放置一个Widget并将其提升为QCustomPlot,这里就不详细介绍,详情可参考:https://blog.csdn.net/didi_ya/article/details/120105121

1.2 widget.h头文件

包含一个槽函数,声明一个变量:

public slots:
    void mouseMove1(QMouseEvent *e);

private:
    QCustomPlot *customPlot;
    QCPItemTracer *tracer;
    QCPItemText *tracerLabel;

1.3 绘制图像

绘制图像代码如下:

customPlot = ui->customPlot;//创建customPlot
 // 生成数据,画出的是抛物线
QVector<double> x(101), y(101); //初始化向量x和y
for (int i=0; i<101; ++i)
{
  x[i] = i/50.0 - 1; // x范围[-1,1]
  y[i] = x[i]*x[i]; // y=x*x
}
customPlot->xAxis->setRange(-1, 1);
customPlot->yAxis->setRange(0, 1);
customPlot->addGraph();
customPlot->graph(0)->setData(x, y); //把数据加入到绘制器cmPlot,绘制器会自动绘制曲线

1.4 生成游标

为了实现随鼠标移动的游标功能,还要加入QCPItemTracer的指针(tracer)和QCPItemText的指针(tracerLabel)作为成员,前者就是游标,后者用于显示游标在曲线上的数据。

生成游标代码如下:

//生成游标
tracer = new QCPItemTracer(customPlot); //生成游标

tracer->setPen(QPen(Qt::red));//圆圈轮廓颜色
tracer->setBrush(QBrush(Qt::red));//圆圈圈内颜色
tracer->setStyle(QCPItemTracer::tsCircle);//圆圈
tracer->setSize(5);//设置大小

1.5 游标说明

代码如下:

//游标说明
tracerLabel = new QCPItemText(customPlot); //生成游标说明
tracerLabel->setLayer("overlay");//设置图层为overlay,因为需要频繁刷新
tracerLabel->setPen(QPen(Qt::black));//设置游标说明颜色
tracerLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);//左上
tracerLabel->position->setParentAnchor(tracer->position);//将游标说明锚固在tracer位置处,实现自动跟随

1.6 mouseMove1函数

函数代码如下:

void Widget::mouseMove1(QMouseEvent *e)
{
    //获得鼠标位置处对应的横坐标数据x
    double x = customPlot->xAxis->pixelToCoord(e->pos().x());
    //double y = cmPlot->yAxis->pixelToCoord(e->pos().y());
    double xValue, yValue;

    xValue = x;//xValue就是游标的横坐标
    yValue = x*x;//yValue就是游标的纵坐标,这里直接根据产生数据的函数获得

    tracer->position->setCoords(xValue, yValue);//设置游标位置
    tracerLabel->setText(QString("x = %1, y = %2").arg(xValue).arg(yValue));//设置游标说明内容
    customPlot->replot();//绘制器一定要重绘,否则看不到游标位置更新情况
}

最后,再加入信号-槽连接语句:

//信号-槽连接语句
    connect(customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove1(QMouseEvent*)));

二、运行结果

在这里插入图片描述

三、拓展

但是上述方法只适合于函数比较简单的情况(比如幂函数或指数函数),计算yValue时计算开销不大,鼠标移动时响应比较迅速。如果函数形式比较复杂,计算量大,那么应该采用以下的方法。

方法2:

void Widget::mouseMove2(QMouseEvent *e)
{
    //获得鼠标位置处对应的横坐标数据x
    double x = customPlot->xAxis->pixelToCoord(e->pos().x());

    tracer->setGraph(customPlot->graph(0)); //将游标和该曲线图层想连接
    tracer->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x
    tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得
    tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效
    //更新游标说明的内容
    double xValue = tracer->position->key();
    double yValue = tracer->position->value();
    tracerLabel->setText(QString("x = %1, y = %2").arg(xValue).arg(yValue));
    customPlot->replot(); //重绘
}

完整代码可以参考:https://download.csdn.net/download/didi_ya/22038184

参考:https://blog.csdn.net/weixin_45875835/article/details/104074736

  • 21
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
QCustomPlot是一个强大的Qt绘图库,可以用于绘制各种静态和动态图形。要在QCustomPlot中绘制动态曲线并显示鼠标悬停位置的坐标,可以按照以下步骤进行: 1. 创建一个QCustomPlot对象,并添加一个QCPGraph对象用于绘制曲线。 2. 设置QCustomPlot对象的x轴和y轴范围。 3. 在一个定时器中更新QCPGraph对象的数据。 4. 为QCustomPlot对象添加一个QCPItemTracer对象,用于跟踪鼠标位置。 5. 在QCustomPlot对象上添加一个QCPItemText对象,用于显示鼠标悬停位置的坐标。 6. 在QCustomPlot对象的鼠标移动事件中更新QCPItemTracer对象的位置和QCPItemText对象的内容。 以下是一个基本示例代码: ```cpp // 创建QCustomPlot对象 QCustomPlot *customPlot = new QCustomPlot(this); // 创建QCPGraph对象,并添加到QCustomPlot对象中 QCPGraph *graph = customPlot->addGraph(); graph->setPen(QPen(Qt::blue)); graph->setBrush(QBrush(QColor(0, 0, 255, 20))); // 设置x轴和y轴范围 customPlot->xAxis->setRange(0, 10); customPlot->yAxis->setRange(0, 10); // 创建QCPItemTracer对象,并添加到QCustomPlot对象中 QCPItemTracer *tracer = new QCPItemTracer(customPlot); customPlot->addItem(tracer); // 创建QCPItemText对象,并添加到QCustomPlot对象中 QCPItemText *textLabel = new QCPItemText(customPlot); customPlot->addItem(textLabel); // 设置定时器,更新QCPGraph对象的数据 QTimer timer; connect(&timer, &QTimer::timeout, [=](){ static double t = 0; QVector<double> x(101), y(101); for (int i=0; i<101; ++i) { x[i] = t + i/100.0; y[i] = sin(x[i]); } graph->setData(x, y); customPlot->replot(); t += 0.1; }); timer.start(50); // 在鼠标移动事件中更新QCPItemTracer对象的位置和QCPItemText对象的内容 connect(customPlot, &QCustomPlot::mouseMove, [=](QMouseEvent *event){ double x = customPlot->xAxis->pixelToCoord(event->x()); double y = customPlot->yAxis->pixelToCoord(event->y()); tracer->setGraph(graph); tracer->setGraphKey(x); tracer->setVisible(true); textLabel->setText(QString("(%1, %2)").arg(x).arg(y)); textLabel->position->setCoords(event->pos()); customPlot->replot(); }); ``` 在上面的示例代码中,我们创建了一个QCustomPlot对象,并在其中绘制了一个动态的sin曲线。我们还添加了一个QCPItemTracer对象和一个QCPItemText对象,用于在鼠标悬停时显示坐标。在定时器的回调函数中,我们更新QCPGraph对象的数据并重新绘制QCustomPlot对象,以实现动态曲线的效果。在鼠标移动事件中,我们更新QCPItemTracer对象的位置和QCPItemText对象的内容,并重新绘制QCustomPlot对象以显示更新后的内容。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wendy_ya

您的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值