QCustomPlot绘图实现光标滑过曲线显示点的坐标

1 篇文章 0 订阅

有两种方法可实现这个效果:

1.通过关联QCustomPlot的mouseMove信号槽事件实现;

2.通过继承QCustomPlot类,重写mouseMove虚函数实现;

这个两个方法都是获取鼠标位置,然后计算出点的坐标值,利用QToolTip显示点坐标的方法。

方向弄清楚了,现在我们去实现出来,go……

一、信号槽方法

1、首先建立一个鼠标移动时间响应函数:

private slots:
	void MyMouseMoveEvent(QMouseEvent *event);

2、将槽函数MyMouseMoveEvent与QCustomPlot的mouseMove信号建立连接。
Plus,这里推荐基于qt5的信号槽连接,因为编译时,基于qt4的connect不会检查信号和槽的参数以及槽函数正确与否,而基于qt5的connect会有这一个检查过程(原来遇见过基于qt4的槽函数没有响应的情况)。

connect(m_pHistoryPlot, &QCustomPlot::mouseMove, this, &HistoryDataView::MyMouseMoveEvent);

3、槽函数实现光标划过曲线显示点坐标功能。
代码有详细注释,这里就不详细讲解。

void HistoryDataView::MyMouseMoveEvent(QMouseEvent* event)
{	
    if (m_pHistoryPlot->graphCount() == 0)
	{
		return;
	}

	//获取鼠标坐标,相对父窗体坐标
	int x_pos = event->pos().x();
	int y_pos = event->pos().y();

	//鼠标坐标转化为CustomPlot内部坐标
	float x_val = m_pHistoryPlot->xAxis->pixelToCoord(x_pos);
	float y_val = m_pHistoryPlot->yAxis->pixelToCoord(y_pos);

	//通过坐标轴范围判断光标是否在点附近
	float x_begin = m_pHistoryPlot->xAxis->range().lower;
	float x_end = m_pHistoryPlot->xAxis->range().upper;
	float y_begin = m_pHistoryPlot->yAxis->range().lower;
	float y_end = m_pHistoryPlot->yAxis->range().upper;
	float x_tolerate = (x_end - x_begin) / 40;//光标与最近点距离在此范围内,便显示该最近点的值
	float y_tolerate = (y_end - y_begin) / 40;

	//判断有没有超出坐标轴范围
	if (x_val < x_begin || x_val > x_end)
	{
		return;
	}

	//通过x值查找离曲线最近的一个key值索引
	int index = 0;
	int index_left = m_pHistoryPlot->graph(0)->findBegin(x_val, true);//左边最近的一个key值索引
	int index_right = m_pHistoryPlot->graph(0)->findEnd(x_val, true);//右边
	float dif_left = fabs(m_pHistoryPlot->graph(0)->data()->at(index_left)->key - x_val);
	float dif_right = fabs(m_pHistoryPlot->graph(0)->data()->at(index_right)->key - x_val);
	index = ((dif_left < dif_right) ? index_left : index_right);

	double x_posval = m_pHistoryPlot->graph(0)->data()->at(index)->key;//通过得到的索引获取key值
	double y_posval = m_pHistoryPlot->graph(0)->data()->at(index)->value;//通过得到的索引获取value值

	float dx = fabs(x_posval - x_val);
	float dy = fabs(y_posval - y_val);

	int graphIndex = 0;//curve index closest to the cursor
	//通过遍历每条曲线在index处的value值,得到离光标点最近的value及对应曲线索引
	for (int i = 0, n = m_pHistoryPlot->xAxis->graphs().count(); i < n; i++)
	{
		y_posval = fabs(m_pHistoryPlot->graph(i)->data()->at(index)->value - y_val);
		if (y_posval < dy)
		{
			dy = y_posval;
			graphIndex = i;
		}
	}

	//判断光标点与最近点的距离是否在设定范围内
	if (dy <= y_tolerate && dx <= x_tolerate)
	{
		y_posval = m_pHistoryPlot->graph(graphIndex)->data()->at(index)->value;

		QString strToolTip = QString("CH%1 \nx=%2\ny=%3").arg(graphIndex + 1).arg(y_posval).arg(y_posval);

		QToolTip::showText(cursor().pos(), strToolTip, m_pHistoryPlot);
	}
}

4、最终效果

二、继承通过虚函数实现

1、继承QCustomPlot

class MyCustomPlot : public QCustomPlot
​​​​​​​{
    Q_OBJECT
public:
    MyCustomPlot(QWidget *parent = 0);

protected:
    virtual void mouseMoveEvent(QMouseEvent *event);
//……
}

2、重写虚函数

void MyCustomPlot::mouseMoveEvent(QMouseEvent *event)
{
    QCustomPlot::mouseMoveEvent(event);

    if(!m_isShowTracer)
    {
        return;
    }
    //获取鼠标坐标,相对父窗体坐标
	int x_pos = event->pos().x();
	int y_pos = event->pos().y();

	//鼠标坐标转化为CustomPlot内部坐标
	float x_val = m_pHistoryPlot->xAxis->pixelToCoord(x_pos);
	float y_val = m_pHistoryPlot->yAxis->pixelToCoord(y_pos);

	//通过坐标轴范围判断光标是否在点附近
	float x_begin = m_pHistoryPlot->xAxis->range().lower;
	float x_end = m_pHistoryPlot->xAxis->range().upper;
	float y_begin = m_pHistoryPlot->yAxis->range().lower;
	float y_end = m_pHistoryPlot->yAxis->range().upper;
	float x_tolerate = (x_end - x_begin) / 40;//光标与最近点距离在此范围内,便显示该最近点的值
	float y_tolerate = (y_end - y_begin) / 40;

	//判断有没有超出坐标轴范围
	if (x_val < x_begin || x_val > x_end)
	{
		return;
	}

	//通过x值查找离曲线最近的一个key值索引
	int index = 0;
	int index_left = m_pHistoryPlot->graph(0)->findBegin(x_val, true);//左边最近的一个key值索引
	int index_right = m_pHistoryPlot->graph(0)->findEnd(x_val, true);//右边
	float dif_left = fabs(m_pHistoryPlot->graph(0)->data()->at(index_left)->key - x_val);
	float dif_right = fabs(m_pHistoryPlot->graph(0)->data()->at(index_right)->key - x_val);
	index = ((dif_left < dif_right) ? index_left : index_right);

	double x_posval = m_pHistoryPlot->graph(0)->data()->at(index)->key;//通过得到的索引获取key值
	double y_posval = m_pHistoryPlot->graph(0)->data()->at(index)->value;//通过得到的索引获取value值

	float dx = fabs(x_posval - x_val);
	float dy = fabs(y_posval - y_val);

	int graphIndex = 0;//curve index closest to the cursor
	//通过遍历每条曲线在index处的value值,得到离光标点最近的value及对应曲线索引
	for (int i = 0, n = m_pHistoryPlot->xAxis->graphs().count(); i < n; i++)
	{
		y_posval = fabs(m_pHistoryPlot->graph(i)->data()->at(index)->value - y_val);
		if (y_posval < dy)
		{
			dy = y_posval;
			graphIndex = i;
		}
	}

	//判断光标点与最近点的距离是否在设定范围内
	if (dy <= y_tolerate && dx <= x_tolerate)
	{
		y_posval = m_pHistoryPlot->graph(graphIndex)->data()->at(index)->value;
		//QString strToolTip = QString("CH%1:(%2, %3)").arg(graphIndex + 1).arg(x_val).arg(y_val);
		int hor = x_posval / 3600;
		int tmp = (int)x_posval % 3600;
		int min = tmp / 60;
		int sec = tmp % 60;
		char arx[32] = { 0 };
		sprintf(arx, "%02d:%02d:%02d", hor, min, sec);
		QString strToolTip = QString("CH%1 \nx=%2\ny=%3").arg(graphIndex + 1).arg(arx).arg(y_posval);

		QToolTip::showText(cursor().pos(), strToolTip, m_pHistoryPlot);
	}

    this->replot();//曲线重绘
}

 QT5下,使用QCustomPlot显示折线图和曲线图,鼠标滑过折线曲线跟随鼠标显示此时鼠标指向的点的x轴数值和y轴数值。

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
QCustomPlot是一个开源的Qt绘图库,它可以用于在应用程序中绘制各种图表和图形。 要在QCustomPlot显示曲线坐标值,我们可以使用以下步骤: 1. 创建一个QCustomPlot对象: ``` QCustomPlot *customPlot = new QCustomPlot(); ``` 2. 创建一个QCPGraph对象,并将其添加到QCustomPlot中: ``` QCPGraph *graph = customPlot->addGraph(); ``` 3. 设置曲线的数据: ``` QVector<double> xData, yData; // 假设这里有x和y坐标数据 // 将数据添加到xData和yData中 graph->setData(xData, yData); ``` 4. 启用坐标显示功能: ``` customPlot->setInteraction(QCP::iSelectPlottables); // 允许选择绘图组件 customPlot->axisRect()->setRangeDrag(Qt::Horizontal | Qt::Vertical); // 允许拖动坐标轴范围 customPlot->axisRect()->setRangeZoom(Qt::Horizontal | Qt::Vertical); // 允许缩放坐标轴范围 graph->setSelectable(QCP::stSingleData); // 允许选择单个数据 ``` 5. 实现槽函数来响应数据的选择事件,在槽函数中获取选择的数据坐标值并显示: ``` QObject::connect(customPlot, &QCustomPlot::plottableClick, this, [=](QCPAbstractPlottable *plottable, int dataIndex) { if (plottable == graph) { double x = xData[dataIndex]; double y = yData[dataIndex]; // 将坐标显示到UI中 } }); ``` 通过上述步骤,我们可以在QCustomPlot显示曲线坐标值。当用户曲线上的数据时,我们可以获得选择的数据坐标值,并将其显示到用户界面上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值