12.QCustomPlot中数据选择机制

数据选择机制

QCustomPlot中,每个绘图表都可以由用户或以编程方式选择。如果用户能够以任何方式选择数据,则必须在QCustomPlot :: setInteractions中设置交互标志QCP :: iSelectPlottables

数据选择粒度

选择粒度可以通过QCPAbstractPlottable :: setSelectable通过指定相应的QCP :: SelectionType来控制。例如,当使用QCP :: stMultipleDataRanges时,用户将完全自由选择自己选择的数据点和不选择的数据点。另一方面,如果我们使用QCP :: stDataRange,则选择机制将强制所选数据始终是一个连续范围。因此,如果用户选择两个遥远的数据点(通常在按住multi-select修饰符的同时Ctrl),则这两个点之间的所有数据点也会被选中。

这些图像显示了拖动指示的选择矩形时不同选择类型的效果:

selectiontype-none.png
无声
selectiontype-whole.png
整个
selectiontype-singledata.png
stSingleData
selectiontype-datarange.png
stDataRange
selectiontype-multipledataranges.png
stMultipleDataRanges

单击选择并选择矩形

用户可以通过两种方式选择数据点:

第一种方法是用鼠标光标单击数据点。在这种情况下,如果用户要一个接一个地选择多个数据点,则必须按住多选修饰符(QCustomPlot :: setMultiSelectModifier),并且必须在QCustomPlot :: setInteractions中设置QCP :: iMultiSelect

另一种方法是将选择矩形拖动到应选择的数据点上。如果QCustomPlot :: setSelectionRectMode设置为QCP :: srmSelect,则有可能。请注意,设置了选择矩形模式(不是QCP :: srmNone)时,鼠标拖动将不会转发到基础布局元素。这也意味着无法再用鼠标拖动轴范围。如果希望为用户提供轴范围拖动和数据选择/范围缩放功能,请在处理交互之前使用QCustomPlot :: setSelectionRectMode在模式之间进行切换,例如,对QCustomPlot :: mousePressQCustomPlot :: mouseMove做出反应信号。例如,您可以检查用户是否持有某个键盘修饰符,然后决定应设置哪种模式。

检索所选数据

一旦通过用户交互或以编程方式更改了绘图表的选择状态,受影响的绘图表将发出信号QCPAbstractPlottable :: selectionChanged,并以QCPDataSelection的形式携带当前选择的数据点。该信号的过载是可用的,它仅指示bool出绘图表是否具有任何选定的数据点。

通过调用QCustomPlot :: selectedPlottables,可以检索当前已选择数据点的绘图表列表。可以通过QCPAbstractPlottable :: selection检索绘图表的当前选择。还有一种专门用于QCPGraph绘图表的方法,称为QCustomPlot :: selectedGraphs

访问数据选择

QCPDataSelection是列表QCPDataRange情况下,其本身持有的开始结束相应数据的范围索引。对于一维绘图表(源自QCPAbstractPlottable1D,例如QCPGraphQCPCurveQCPBars等),可以使用数据容器的at(int index)方法按索引访问数据点。或者,您可以简单地将整数索引添加到数据容器的begin()迭代器中。

例如,以下代码片段计算图形数据选择的平均值:

 QCPDataSelection selection = graph->selection();
  double sum = 0;
  foreach (QCPDataRange dataRange, selection.dataRanges())
  {
    QCPGraphDataContainer::const_iterator begin = graph->data()->at(dataRange.begin()); // get range begin iterator from index
    QCPGraphDataContainer::const_iterator end = graph->data()->at(dataRange.end()); // get range end iterator from index
    for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it)
    {
      // iterator "it" will go through all selected data points, as an example, we calculate the value average
      sum += it->value;
    }
  }
  double average = sum/selection.dataPointCount();
 
平均值=总和/选择。dataPointCount();

由于QCPDataSelection实例未与特定的绘图表紧密绑定,因此它们包含的索引可能超出了绘图表的有效数据范围。可通过访问绘图表的数据容器并调用QCPDataContainer :: dataRange来检索有效数据范围。这样,您可以检查给定的QCPDataSelection是否包含在有效范围内,并在必要时通过分别使用QCPDataSelection :: containsQCPDataSelection :: intersection对其进行修整

当然,只要检索选择后未更改,由QCPAbstractPlottable :: selection返回的数据选择始终在绘图表的数据范围内。

检索给定像素位置的数据点

如果只想找出某个绘图表的哪个数据点在给定的像素位置处或附近(不需要单击或实际选择事件),则可以使用QCPAbstractPlottable :: selectTest。例如,以下代码检索在像素坐标中最接近给定QPoint的数据点的迭代器:

 

QCPGraphDataContainer::const_iterator it = graph->data()->constEnd();
  QVariant details;
  if (graph->selectTest(QPoint(123, 456), false, &details)) // QPoint could be e.g. event->pos() of a mouse event
  {
    QCPDataSelection dataPoints = details.value<QCPDataSelection>();
    if (dataPoints.dataPointCount() > 0)
      it = graph->data()->at(dataPoints.dataRange().begin());
  }
  // iterator "it" now carries the data point at pixel coordinates (123, 456), or constEnd if no data point was hit.

 

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用QCustomPlot的信号和槽机制实现鼠标悬停显示数据。具体步骤如下: 1. 在绘制曲线之前,设置曲线对象的可选项`setSelectable(QCP::stSingleData)`,表示数据点可以被选择。 2. 连接鼠标悬停事件`QCustomPlot::plottableMouseMove`和槽函数`QCustomPlot::plottableClick`。在槽函数获取鼠标所在位置的数据点,然后在图例下面添加一个QCPItemText对象,用于显示数据。 下面是一个示例代码: ``` // 创建曲线对象 QCPGraph *graph = ui->plot->addGraph(); graph->setData(x, y); // 设置曲线可选项 graph->setSelectable(QCP::stSingleData); // 连接鼠标悬停事件和槽函数 connect(ui->plot, SIGNAL(plottableMouseMove(QMouseEvent*)), this, SLOT(onMouseMove(QMouseEvent*))); // 定义槽函数 void MyWidget::onMouseMove(QMouseEvent *event) { QCustomPlot *plot = ui->plot; double x = plot->xAxis->pixelToCoord(event->pos().x()); double y = plot->yAxis->pixelToCoord(event->pos().y()); QCPGraph *graph = qobject_cast<QCPGraph*>(plot->plottableAt(event->pos())); if (graph) { int dataIndex = graph->data()->findBegin(x)->key; double dataValue = graph->data()->value(dataIndex)->value; QString text = QString("x=%1, y=%2").arg(x).arg(dataValue); QCPItemText *textLabel = new QCPItemText(plot); textLabel->setText(text); textLabel->position->setType(QCPItemPosition::ptPlotCoords); textLabel->position->setCoords(x, dataValue); textLabel->setFont(QFont("Arial", 10)); textLabel->setPadding(QMargins(5, 5, 5, 5)); plot->addItem(textLabel); } } ``` 这样,当鼠标悬停在曲线上时,就会在数据点上方显示数据

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值