QCustomPlot之光标划过曲线显示点的坐标
程序员文章站
2022-06-13 21:20:41
...
在网上查了这方面的内容,几乎清一色的都是主要用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);
}
效果:
上一篇: JavaIo