在QCustomPlot中,每个绘图表都可以由用户或以编程方式选择。如果用户能够以任何方式选择数据,则必须在QCustomPlot :: setInteractions中设置交互标志QCP :: iSelectPlottables。
数据选择粒度
选择粒度可以通过QCPAbstractPlottable :: setSelectable通过指定相应的QCP :: SelectionType来控制。例如,当使用QCP :: stMultipleDataRanges时,用户将完全自由选择自己选择的数据点和不选择的数据点。另一方面,如果我们使用QCP :: stDataRange,则选择机制将强制所选数据始终是一个连续范围。因此,如果用户选择两个遥远的数据点(通常在按住multi-select修饰符的同时Ctrl
),则这两个点之间的所有数据点也会被选中。
这些图像显示了拖动指示的选择矩形时不同选择类型的效果:
![]()
无声
|
![]()
整个
|
![]()
stSingleData
|
![]()
stDataRange
|
![]()
stMultipleDataRanges
|
单击选择并选择矩形
用户可以通过两种方式选择数据点:
第一种方法是用鼠标光标单击数据点。在这种情况下,如果用户要一个接一个地选择多个数据点,则必须按住多选修饰符(QCustomPlot :: setMultiSelectModifier),并且必须在QCustomPlot :: setInteractions中设置QCP :: iMultiSelect。
另一种方法是将选择矩形拖动到应选择的数据点上。如果QCustomPlot :: setSelectionRectMode设置为QCP :: srmSelect,则有可能。请注意,设置了选择矩形模式(不是QCP :: srmNone)时,鼠标拖动将不会转发到基础布局元素。这也意味着无法再用鼠标拖动轴范围。如果希望为用户提供轴范围拖动和数据选择/范围缩放功能,请在处理交互之前使用QCustomPlot :: setSelectionRectMode在模式之间进行切换,例如,对QCustomPlot :: mousePress或QCustomPlot :: mouseMove做出反应信号。例如,您可以检查用户是否持有某个键盘修饰符,然后决定应设置哪种模式。
检索所选数据
一旦通过用户交互或以编程方式更改了绘图表的选择状态,受影响的绘图表将发出信号QCPAbstractPlottable :: selectionChanged,并以QCPDataSelection的形式携带当前选择的数据点。该信号的过载是可用的,它仅指示bool
出绘图表是否具有任何选定的数据点。
通过调用QCustomPlot :: selectedPlottables,可以检索当前已选择数据点的绘图表列表。可以通过QCPAbstractPlottable :: selection检索绘图表的当前选择。还有一种专门用于QCPGraph绘图表的方法,称为QCustomPlot :: selectedGraphs。
访问数据选择
甲QCPDataSelection是列表QCPDataRange情况下,其本身持有的开始和结束相应数据的范围索引。对于一维绘图表(源自QCPAbstractPlottable1D,例如QCPGraph,QCPCurve,QCPBars等),可以使用数据容器的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();
由于QCPDataSelection实例未与特定的绘图表紧密绑定,因此它们包含的索引可能超出了绘图表的有效数据范围。可通过访问绘图表的数据容器并调用QCPDataContainer :: dataRange来检索有效数据范围。这样,您可以检查给定的QCPDataSelection是否包含在有效范围内,并在必要时通过分别使用QCPDataSelection :: contains和QCPDataSelection :: 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.