QCustomPlot之光标划过曲线显示点的坐标

16 篇文章 0 订阅

在网上查了这方面的内容,几乎清一色的都是主要用QCPItemTracer和QCPItemText这两个类实现的,实现代码冗长,现在的我还没有搞懂。最后,发现通过QToolTip实现该功能是个挺简便的方法,能实现一个函数就搞定了,保证了代码的轻量级,随拿随用,下面就给出代码实现(qt 5.13 +vs2017+ C++)。
(1)首先建立一个鼠标移动时间响应函数:

private slots:
	void myMouseMoveEvent(QMouseEvent *event);

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

connect(ui.customPlot, &QCustomPlot::mouseMove, this, &AnalysisWidget::myMouseMoveEvent);

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

void AnalysisWidget::myMouseMoveEvent(QMouseEvent *event)
{
	if (ui.customPlot->graphCount() == 0)
		return;

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

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

	//通过坐标轴范围判断光标是否在点附近
	float x_begin = ui.customPlot->xAxis->range().lower;
	float x_end = ui.customPlot->xAxis->range().upper;
	float y_begin = ui.customPlot->yAxis->range().lower;
	float y_end = ui.customPlot->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 = ui.customPlot->graph(0)->findBegin(x_val, true);//左边最近的一个key值索引
	int index_right = ui.customPlot->graph(0)->findEnd(x_val, true);//右边
	float dif_left = abs(ui.customPlot->graph(0)->data()->at(index_left)->key - x_val);
	float dif_right = abs(ui.customPlot->graph(0)->data()->at(index_right)->key - x_val);
	if (dif_left < dif_right)
		index = index_left;
	else
		index = index_right;

	x_val = ui.customPlot->graph(0)->data()->at(index)->key;//通过得到的索引获取key值

	int graphIndex=0;//curve index closest to the cursor	
	float dx = abs(x_val - ui.customPlot->xAxis->pixelToCoord(x_pos));
	float dy= abs(ui.customPlot->graph(0)->data()->at(index)->value - y_val);

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

	QString strToolTip = "测量点" + QString::number(graphIndex + 1) + ": (";
	strToolTip += QString::number(x_val, 10, 4) + ", ";
	strToolTip += QString::number(ui.customPlot->graph(graphIndex)->data()->at(index)->value) + ")";

	//判断光标点与最近点的距离是否在设定范围内
	if (dy < y_tolerate && dx < x_tolerate)
		QToolTip::showText(cursor().pos(), strToolTip, ui.customPlot);
}

效果:
在这里插入图片描述

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值