Qt:QCustomPlot使用教程(三)——用户交互

0、说明

本节翻译总结自:Qt Plotting Widget QCustomPlot - User Interactions

本节内容是使用QCustomPlot实现绘图和用户交互功能。

本文代码中的变量customPlot是QCustomPlot类型的指针,实际使用时,应当用ui->customPlot,表示UI界面中用于绘图的QCustomPlot。

QCustomPlot提供了多种内置的用户交互方法,这些方法可以分类归纳如下:

  • 范围调整:通过鼠标拖拽或者鼠标滚轮实现;
  • 选择要素:通过鼠标点击;
  • 点击实例时发送信号。

1、范围调整

默认情况下,用户调整坐标轴范围的方法是在分别在对应的QCPAxisRect上进行拖拽。

为了实现在QCustomPlot上实现范围拖拽,需要在当前允许的交互上增加Flag QCP::iRangeDrag。这一点可以通过customPlot -> setInteraction( QCP::iRangeDrag , true)做到。如果想要只允许在一个方向上拖拽,可以用QCPAxisRect::setRangeDrag并且制定参数为Qt::Vertical或Qt::Horizontal。如果想允许在所有方向上拖拽(当然这也是默认的),可以用 Qt::Vertical | Qt::Horizontal 作为参数。

在拖拽过程中,通过QCPAxisRect::setRangeDragAxes设置的轴将会实时更新其范围;这将会给用户通过抓取坐标平面来实现移动坐标系的感觉。默认的QCustomPlot的轴是QCustomPlot::xAxisQCustomPlot::yAxis

以上只是改变了范围的区间,如果我们想改变范围的大小,例如缩放图像,用户可能会用鼠标滚轮。该行为是通过Flag QCP::iRangeZoom控制的,当然它也需要用QCustomPlot::setInteraction来激活。和拖拽类似,对于缩放的轴和方向也是可以选择的,具体可以看函数QCPAxisRect::setRangeZoomAxes 和 QCPAxisRect::setRangeZoom。除此之外,缩放因子(滚动一次滚轮时缩放倍数)由QCPAxisRect::setRangeZoomFactor决定。

2、选择要素

2.1、某一类要素的选择

QCustomPlot提供了要素选择的机制,允许用户选择画布上的任意要素,例如坐标轴和图像。

某一类要素是否可以选中,是通过在setInteraction方法中设置Flag QCP::iSelect(...)来实现的。例如,通过设置customPlot -> setInteraction( QCP::iSelectPlottables , true )就允许用户通过点击的方法来选中Plottable(比如图像)。通过参考文档QCP::Interaction可以获取全部交互Flag。

如果想要同时选中多个要素,可以设置交互Flag QCP::iMultiSelect。这样用户就可以拖过按CTRL键,依次选中多个要素。(这个键位可以通过QCustomPlot::setMultiSelectModifier修改)。

被选中的要素会用加粗的蓝色线条绘制。

2.2、控制单个要素的选择

对某个具体对象的可选属性,可以用setSelectable方法进行调整。例如,如果我们不想某个图像被用户选择,可以用方法thatGraph->setSelectable(false)。

要素的选择状态可以用setSelected函数进行调整,这样的话,即使某个要素是无法选中的(通过上一段的方法),我们依然可以通过该方法来在程序中通过上述方法修改它的状态为选中的。

如果要取消对于画板上所有要素的选择,可以用QCustomPlot::deselectAll

2.3、被选择要素的外观

一个被选中的要素通常会用和它原来绘制方式不同的画笔、刷子、字体来显示。这一点可以通过方法QCPGraph::setSelectedPenQCPGraph::setSelectedBrushQCPAxis::setSelectedLabelFontQCPAxis::setSelectedBasePenQCPItemText::setSelectedColor

来进行修改。至于这些方法的含义,可以很容易从它们的名字中看出来。

这些方法,和一开始绘制要素时的方法名十分相似,就是加了前缀"Selected"。

2.4、要素的多个组成部分

一些要素(比如坐标轴、图例)可能有多个组成部分,这时如果我们只用一个boolean参数来表示选择状态就不太合适了。这种情况下,不管是可选择性还是选中状态,都应当是SelectablePart的Flag的一组 or组合,也就是说,不同的组分要分别通过它们各自的QFlag的组合(通过or连接)来说明。

每个多组分的要素都需要定义一个它自己的SelectablePart。

例如,QCPAxis通常是由三部分组成的——刻度线、刻度数字、轴标签(如下)。

Qt:QCustomPlot使用教程(三)——用户交互

 

 

 因此这三部分都需要各自指明它们的可选择性,QCPAxis::SelectablePart定义了QCPAxis::spNoneQCPAxis::spAxisQCPAxis::spTickLabelsQCPAxis::spAxisLabel。如果想要刻度线和刻度数字可选,但是轴标签不可选,可以用theAxis->setSelectableParts(QCPAxis::spAxis|QCP::spTickLabels)。

如果想控制当前的多组分选择状态,可以用QCPAxis::setSelectedParts方法。

2.5、对要素选中状态的响应

每当选中要素改变时,每个要素都会发送一个信号selectionChanged。不管这个改变是由于用户自主选择引起的还是程序中通过调用方法setSelected/setSelectedParts引起的。

如果是由于用户交互引起的改变,会发送QCustomPlot::selectionChangedByUser信号。在该信号的槽函数中,我们可以检查特定要素的选中状态并对其做出反应。如果要检查某种特定类型的选中,可以用方法QCustomPlot::selectedPlottablesselectedItemsselectedAxesselectedLegends

3、用户交互信号

用户交互信号与选择机制是相互独立的,QCustomPlot会基于用户的操作发送多重信号。最低级的信号是QCustomPlot::mouseDoubleClick、mousePress、mouseMove、mouseRelease和mouseWheel信号,这些信号的发送时机,可以从它们的名字中看出来。

也有一些高级的信号,它们表示在具体对象上发生的事件——QCustomPlot::plottableClick、plottableDoubleClick、itemClick、itemDoubleClick、axisClick、axisDoubleClick、legendClick、legendDoubleClick、titleClick和titleDoubleClick。

所有这些信号都表示了具体哪个要素被点击了,正如和QMouseEvent相关的事件那样。

案例Package中包含了一个使用多方面用户交互系统的例子(这里不再说明),它也告诉了我们如何改进交互系统以更好满足我们需求的方法。

 

上一篇:分享一个非常强大且好用的绘图控件QCustomPlot


下一篇:QCustomPlot基础教程(三)——在Qt中绘制多条曲线(拓展)