Qt之QCustomPlot

在学完各种dll的调用方式和QAbstractItemModel之后,终于到了这一步,之前用过CustomPlot来实现简单图的绘制,但是这次我需要从头开始,理解内涵

文章目录

1 Main Page

1.1 QCustomPlot 2.0.1 Documentation

如果你是QCustomPlot的新手,并且你准备开始使用它,我们建议你在官网中看看先关的教程和范例。
此文档尤其适合当做参考文档,当你学会了QCustomPlot的基本可视化的语法以后,并且希望学习更多的特殊的功能和更先进的概念,可以看看 class overview 章节的看QCustomPlot库中的重要的类

1.2 Plottables 绘图板

Plottables 是用来显示 QCustomPlot 中任意的数据的类,他们都从类 QCPAbstractPlottable 中所派生出来,QCPGraph 是一个 plottable,可以显示用不同的方式,比如线型,散点型,填充型的图像。
因为绘制图像是很重要的情况, QCustomPlot 有一个为 QCPGraph plottables 工作的特殊的接口,这让我们很简单的操作他们:
一个新的图像可以通过 QCustomPlot::addGraph 来创建,然后可以通过 QCustomPlot::graph 来访问。
对于其他的 plottables,普通的 plottable 的接口是如下使用的,首先,创造各自 plottables 的实例,然后添加到 QCustomPlot 中,如下所示

QCPCurve *newCurve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);

新创建的 plottable 的特性可以通过 newCurve 点来访问。
Plottables(包括graphs)可以通过 QCustomPlot::plottable 来检索,因为这个函数的返回值是所有plottables的纯虚基类,QCPAbsrtactPlottable,你可能希望使用 qobject)cast 来返回指向各自的绘图板(以下用绘图板来代表plottable)的子类的指针,通常来说,如果绘图板不是指定的子类的话,cast将返回zero。
所有绘图板的接口(比如如何设置数据)都指定成绘图板类型,详细的可以看子类的文档,QCPGraph,QCPCurve,QCPBars,QCPStatisticalBox,QCPColorMap,QCPFinancial。

1.3 Controlling the Axes 坐标轴的操控

QCustomPlot 有4个默认的坐标轴,分别是,xAxis(下方),yAxis(左方),xAxis2(上方)和yAxis2(右方)。
他们的范围是由简单的类 QCPRange 来控制的,这个类基本保持了上下轴的相同的坐标,你可以使用函数 QCPAxis::setRange 来设置范围,为了将坐标轴的缩放类型从线性缩放改为对数缩放,可以设置 QCPAxis::setScaleTypeQCPAxis::stLogarithmic,在这种情况下,您还需要对数间隔的刻度和刻度标签,因此设置坐标轴标签从 QCPAxis::setTickerQCPAxisTickerLog 实例。
每一个坐标轴可以通过函数 QCPAxis::setLabel 来设定坐标轴标签比如,“Voltage(mV)”
默认情况下,会自动的创建坐标轴,并且坐标轴标签会用智能的方式存在,细微调节的话,看 QCPAxis 文档的更多的方法,标签可以通过 QCPAxis::setTicks 来禁用,如果你仅仅希望隐藏刻度标签(数据),使用 QCPAxis::setTickLabels 需要注意的是,默认的右边和上边的左边轴一开始是隐藏刻度标签的。
坐标轴主轴到绘图窗体的距离我们叫边缘,边缘是自动计算的,需要填充左边轴和刻度线,为了改变这种情况,设置 QCPAxisRect::setAutoMargins 来排斥各自的边界,并且通过 QCPAxisRect::setMargins手动设置边界,主要的坐标轴矩形可以通过 QCustomPlot::axisRect() 来访问,详细的关于 边界/填充/偏移(margins/paddings/offset) 的解释在 QCPAxisRectQCPAxis 文档中说明

1.4 Plot Legend 绘制图例

每一个 QCustomPlot 默认情况下都有一个 QCPLegend(作为QCustomPlot::legend),图例是一个小的布局单元,放置在绘图区域中,它列出了一个绘图板的线性或图标,还有绘图板的名称(通过QCPAbstractPlottable::setName 来设定)。绘图板可以通过函数 QCPAbstractPlottable::addToLegendQCPAbstratPlottable::removeFromLegend 来添加或者移除图例。默认情况下,在往 QCustomPlot 中添加绘图板的时候,默认已经添加了图例,这个特性可以通过属性 QCustomPlot::setAutoAddPlottableToLegend 来改变。
QCPLegend 提供了一个接口来访问,添加,和移除图例的直接的方式。请看 QCPLegend::item,QCPLegend::itemWithPlottable, QCPLegend::addItem,QCPLegend::removeItem 的例子
多重图例通过布局系统来提供支持,因为 QCPLegend 是一个普通的布局单元

User Interaction 用户交互

QCustomPlot 支持通过鼠标来拖拽坐标轴的范围(QCPAxisRect::setRangeDrag),通过鼠标滚轮来缩放坐标轴的范围(QCPAxisRect::setRangeZoom)和一个完整的选择机制,可以通过数据点的位置和范围来配置。
这些可用的交互方式由 QCustomPlot::setInteractions 来控制,详细的交互方式,请看文档,数据选择的细节在专门的 Data Selection Mechanism 页面
除此之外,QCustomPlot 通常会发射下面的信号,当对象被单击或双击后,请看 QCustomPlot::plottableClickQCustomPlot::plottableDoubleClick,和 QCustomPlot::axisClick 的例子
最后,最低级的控制 QCPLayerable 的鼠标的事件的虚函数,可以自己去创造子类,QCustomPlot 的实例调用受影响的 布局

1.5 Decorations and Auxiliary Items 声明和辅助项目

除了绘图板之外,有另外一个绘制的对象是很重要的:Item(下面用项目来代替item),所有的项目的基类是 QCPAbstractItem,项目和绘图板分开,这样的话项目就不依赖任何的坐标轴,这意味着项目可以放置在像素的绝对位置或者矩形区域的相对位置。除此之外,项目通常不直接显示数据,而是扮演着装饰,强调和描述等作用。
多个项目可以被排列成父子关系用于动态的表现行为,打个比方,你可以配置一个箭头固定在绘图的坐标上。通常这种方式用来指示绘图中重要的区域,同时箭头的尾端可以固定在一个刻度线的中上方,取决于用户把坐标轴放在什么地方,这样箭头就会拉伸和旋转,所以它总是从标签指向指定的绘图坐标,而不需要任何其他的代码。
更多的介绍,请看 QCPAbstractItem 文档,以及各个项目的标准文档,来找出如何使用他们。

1.6 Layout Elements and Layouts 布局元素和布局

QCustomPlot 使用内部的布局系统提供动态的尺寸和位置的变化,比如轴矩形,图例,颜色缩放,和其他的布局单元,他们都是基于 QCPLayoutElement 并且都将他们放置在一个 QCPLayout 的子类中进行安排,像 QCPLayoutGrid
详细的请看 layout system

1.7 OpenGL Accelerated Ploting and Performance Improvement OpenGL加速和性能提升

QCustomPlots 有多重的OpenGL后端支持来提升OpenGL硬件加速绘制,支持所有的Qt版本,如果电脑支持OpenGL,你可以通过代码 QCUSTOMPLOT_USE_OPENGL 并且简单的调用 setOpenGl(true) 在各自的 QCustomPlot 实例中,更多的细节请看此主题的文档。
关于最大化提升绘制的效率在文档页面 Plot Performance Improvement 中提及。

1.8 Preprocessor Define Flags 预处理定义

QCustomPlot 解析一些预处理的定义,有助于debug和编译,这些定义必须定义在包含的 QCustomPlot 头文件之前,通常来说最好的方式是添加在qmake中:DEFINES += QCUSTOMPLOT_USE_OPENGL

  • QCUSTOMPLOT_USE_OPENGL:如果定义了这个,QCustomPlot 可以使用 OpenGL 来提升图像的绘制性能,看 QCustomPlot::setOpenGl
  • QCUSTOMPLOT_COMPILE_LIBRARY:当需要将QCustomPlot定义为共享库的时候需要添加此宏
  • QCUSTOMPLOT_USE_LIBRARY:在包含 QCustomPlot 的头文件的之前定义此宏,当使用 QCustomPlot 作为动态库来使用的时候
  • QCUSTOMPLOT_CHECK_DATA:如果定义了此宏,QCustomPlot 的绘图板将会在每一次的图像重绘的时候验证数据,他将会输出qDubug的输出,编码数据的。

1.9 Using QCustomPlot with special Qt flags 使用带有特殊的Qt flag的 QCustomPlot

See the page Special Qt Flags if your project uses QT_NO_CAST_FROM_ASCII, QT_NO_CAST_TO_ASCII or QT_NO_KEYWORDS.

2 介绍核心类 QCustomPlot Class

本类是本库的核心类,这是一个QWidget,可以显示一个图像还支持和用户互动
继承 QWidget

2.1 Public Types

本类中有两个枚举

  • enum LayerInsertMode:定义了层次相对另外一个层次是如何插入的
  • enum RefreshPriority:定义了在重绘后什么时候QCustomPlot的表面刷新被刷新

LayerInsertMode

枚举名称枚举含义
limBelow层次在其他层次下方插入
limAbove层次在其他层次上方插入

RefreshPriority

枚举名称枚举含义
rplmmediateRefresh在重绘图后通过调用QWidget::repaint()函数来立刻重绘图表和窗体
rpQueuedRefresh在重绘后通过调用QWidget::update()函数来立刻重绘图表,单对窗体的重绘进行排队。这种方式可以降低多个冗余的窗体的重绘
rpRefreshHint使用即时刷新或者队列刷新取决于是否设置了 QCP::phImmediateRefresh 是否设置,看 setPlottingHints
rpQueuedReplot为下一个事件循环迭代排队整个重绘工作,这种方式下,可以避免多个冗余的重绘,实际的重绘取决于 rpRefreshHint 优先级

2.2 Public Functions

QCustomPlot(QWidget *parent = 0)
QRect viewport() const
double bufferDevicePixelRatio() const
QPixmap background() const
bool backgroundScaled() const
Qt::AspectRatioMode backgroundScaledMode() const
QCPLayoutGrid* plotLayout() const
QCP::AntialiasedElements antialiasedElements() const
QCP::AntialiasedElements notAntialiasedElements() const
bool autoAddPlottableToLegend() const
const QCP::Interactions interactions() const
int selectionTolerance() const
bool noAntialiasingOnDrag() const
QCP::PlottingHints plottingHints() const
Qt::KeyboardModifier multiSelectModifier() const
QCP::SelectionRectMode selectionRectMode() const
QCPSelectionRect* selectionRect() const
bool openGl() const
void setViewport(const QRect &rect)
void setBufferDevicePixelRatio(double ratio)
void setBackground(const QPixmap &pm)
void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode = Qt::keepAspectRatioByExpanding)
void setBackground(const QBrush &brush)
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setAntialiasedElements(const QCP::AntialiasedElement &antialiasedElements)
void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled = true)
void setNotAntialiasedElements(const QCP::AntialiasedElements &notAntialiasedEmlements)
void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled = true)
void setAutoAdPlottableToLegend(bool on)
void setInteractions(const QCP::Interactions &interactions)
void setInteraction(const QCP::Interaction &interaction, bool enabled = true)
void setSectionTolerance(int pixels)
void setNoAntialiasingOnDrag(bool enabled)
void setPlottingHints(const QCP::PlottingHints &Hints)
void setMultiSelectModifier(Qt::KeyboardModifier modifier)
void setSelectionRectMode(QCP::SelectionRectMode mode)
void setSelectionRect(QCPSelectionRect *selectionRect)
void setOpenGl(bool enabled, int multisampling = 16)
QCPAbstractPlottable * plottable(int index)
QCPAbstractPlottable * plottable()
bool removePlottable(QCPAbstractPlottable * plottable)
bool removePolttable(int index)
int clearPlottables()
int plottableCount() const
QList<QCPAbstractPlottable *> selectedPlottables() const
QCPAbstractPlottable * plottableAt(const QPointF &pos, bool onlySelectable = false)const
bool hasPlottable(QCPAbstractPlottable * plottable) const
QCPGraph * graph(int index) const
QCPGraph * graph() const
QCPGraph * addGraph(QCPAxis * keyAxis = 0, QCPAxis * valueAxis = 0)
bool removeGraph(QCPGraph * graph)
bool removeGraph(int index)
int clearGraphs()
int graphCount() const
QList<QCPGraph * >selectedGraphs() const
QCPAbstractItem * item(int index) const
QCPAbstractItem * item() const
bool removeItem(QCPAbstractItem *item)
bool removeItem(int index)
int clearItems()
int itemCount() const
QList<QCPAbstractItem *> selectedItems() const
QCPAbstractItem * itemAt(const QPointF &pos, bool onlySelectable = false) const
bool hasItem(QCPAbstractItem *item) const
QCPLayer * layer(const QString &name) const
QCPLayer * layer(int index) const
QCPLayer * currentLayer() const
bool setCurrentLayer(const QString &name)
bool setCurrentLayer(QCPLayer *layer)
int layerCount() const
bool addLayer(const QString &name, QCPLayer * otherLayer = 0, LayerInsertMode insertMode = limAbover)
bool removeLayer(QCPLayer * layer)
bool moveLayer(QCPLayer *layer, QCPLayer * otherLayer, LayerInsertMode insertMode = limAbove)
int axisRectCount() const
QCPAxisRect * axisRect(int index = 0) const
QList<QCPAxisRect *> axisRects() count
QCPLayoutElement * layoutElementAt(const QPointF &pos) const
QCPAxisRect * axisRectAt(const QPointF &pos) const
Q_SLOT void rescaleAxes(bool onlyVisablePlottables = false)
QList<QCPAxis *> selectedAxes() const
QList<QCPLegend *> selectedLegends() const
Q_SLOT void deselectAll()
bool savePdf(const QString &fileName, int width = 0, int height = 0, QCP::ExportPen exportPen = QCP::epAllowCosmetic, const QString &pdfCreater = QString(), const QString &pdfTitle = QString())
bool savePng(const QString &fileName, int width = 0, int height = 0, double scale = 1.0, int quality = -1, int resolution = 96, QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch)
bool saveBmp(const QString &fileName, int width = 0, int heigth = 0, double sacle = 1.0, int resolution = 96, QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch)
bool saveRestered(const QString &fileName, int width, int height, double scale, const char *format, int quality = -1, int resolution = 96, QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch)
QPixmap toPixmap(int width = 0, int height = 0, double scale = 1.0)
void toPainter(QCPPainter *painter, int width = 0, int height = 0)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority = QCustomPlot::rpRefreshHint)

2.3 Public Members

QCPAxis * xAxis
QCPAxis * yAxis
QCPAxis * xAxis2
QCPAxis * yAxis2
QCPLegend * legend

2.4 Signals

void mouseDoubleClick(QMouseEvent * event)
void mousePress(QMouseEvent * event)
void mouseMove(QMouseEvent * event)
void mouseRelease(QMouseEvent * event)
void mouseWheel(QWheelEvent * event)
void plottableClick(QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent *event)
void plottableDoubleClick(QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent * event)
void itemClick(QCPAbstractItem *item, QMouseEvent *event)
void itemDoubleClick(QCPAbstractItem * item, QMouseEvent *event)
void axisClick(QCPAxis *axis, QCPAxis::SelectablePart, QMouseEvent *event)
void axisDoubleClick(QCPAxis * axis, QCPAxis::SelectablePart, QMouseEvent *event)
void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
void selectionChangedByUser()
void beforeReplot()
void afterReplot()

2.5 Protected Functions

virtual QSize minimumSizeHint() const
virtual QSize sizeHint() const
virtual void paintEvent(QPaintEvent *event)
virtual void resizeEvent(QResizeEvent *event)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
virtual void mousePressEvent(QMouseEvent *event)
virtual void mouseMoveEvent(QMouseEvent *event)
virtual void mouseReleaseEvent(QMouseEvent *event)
virtual void wheelEvent(QWheelEvent *event)
virtual void draw(QCPPainter *painter)
virtual void updateLayout()
virtual void axisRemoved(QCPAxis *axis)
virtual void legendRemoved(QCPLegend *legend)
virtual Q_SLOT void processRectSelection(QRect rect, QMouseEvent *event)
virtual Q_SLOT void processRectZoom(QRect rect, QMouseEvent *event)
virtual Q_SLOT void processPointSelection(QMouseEvent *event)
bool registerPlottable(QCPAbstractPlottable *plottable)
bool registerGraph(QCPGraph *graph)
bool registerItem(QCPAbstractItem *item)
void updateLayerIndices() const
QCPLayerable * layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails = 0) const
QList<QCPLayerable *> layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails = 0) const
void drawBackground(QCPPainter *painter)
void setupPaintBuffers()
QCPAbstractPaintBuffer * createPaintBuffer()
bool hasInvalidatePaintBuffers()
bool setupOpenGl()
bool freeOpenGl()

2.6 Detail Description

2.6.1 Constructor & Destructor Documentation 构造和析构

QCustomPlot::QCustomPlot(QWidget* parent = 0) [explicit]

构造一个 CustomPlot,并给它设置默认的值

2.6.2 Member Function Documentation 成员函数

QCPLayoutGrid * QCustomPlot::plotLayout() const [inline]

返回指定的 CustomPlot 实例的顶层布局,最初只包含一个单元,里面只有一个主 QCPAxisRect

QCPSelectionRect * QCustomPlot::selectionRect() const [inline]

允许访问当前使用的 QCPSelectionRect 实例(或者其子类),用来控制绘制矩形操作交互

void QCustomPlot::setViewport(const QRect & rect)

设置 QCustomPlot 的视图口,通常用户无需手动改变视图口。
视图口是图像绘制的区域,所有的设备,比如边缘计算使用视图口作为图像绘制的边界。视图口正常是 QCustomPlot 的rect(),比如一个左上角为(0,0),然后尺寸是 QCustomPlot 窗体。
不要将视图口和坐标轴矩形(QCustomPlot::axisRect)所混淆,坐标轴矩形通常是由4个轴线所围成的区域,图像和绘图板绘制在这个区域内,视图口比它要大,还包括坐标轴本身,刻度值,他们的标签,或者甚至包含附加的坐标轴矩形,颜色缩放和其他的布局单元。
此函数用来允许任意尺寸的输出到 Pixmap,savePng,savePdf中,通过临时的改变视图口的尺寸。

void QCustomPlot::setBufferDevicePixelRatio(double ratio)

设置设备的像素比例,通过使用本 QCustomPlot 实例的绘图缓存
通常来说,这不需要自己手动设置,因为它使用 QWidget::devicePixelRetio 来初始化来适应设备显示
设备的像素比例是由Qt5.4版本以上开始支持的,如果所使用的的Qt版本不够搞,则会将分辨率比例设置为1

void QCustomPlot::setBackground(const QPixmap & pm)

将pm设置为视图口的背景pixmap,通常此pm绘制在所有的对象的下面。
有一种情况是所提供的的pixmap和视图口有不同的尺寸,可以通过函数 setBackgroundScaled来缩放模式(是否以及如何保留高宽比)可用函数 setBackgroundScaledMode来设置,如果需要在一次函数调用中设置所有的选项,考虑使用这个函数的重载版本。
如果通过函数 setBackground(const QBrush &brush)设置了背景刷,视图口想会首先在绘制背景pixmap之前被背景刷来填充,这样在使用半透明的pixmap时比较有用。

void QCustomPlot::setBackground(const QPixmap & pm, bool scaled, Qt::AspectRatioMode mode = Qt::KeepAspectRatioByExpanding)

这是一个重载函数
允许设置视图口的背景pixmap,以及是否需要缩放和以及如何缩放

void QCustomPlot::setBackground(const QBrush &brush)

通过刷子设置视图口的背景
除了绘制各种东西之外,背景也由刷子来填充,如果背景pixmap已经通过函数 setBackground(const QPixmap &pm)来设置后,刷子将会在背景pixmap绘制之前填充视图口,对于pixmap的透明效果是很有用的。
通过Qt::NoBrush 或者 Qt::Transparent来设置刷子来离开透明背景,这杜宇导出图像格式是很有用的,比如保存png

void QCustomPlot::setBackgroundScaled(bool scaled)

设置视图口的背景pixmap是如何通过缩放来适应视图口的,如果缩放设置为true,使用setBackgroundScaledMode控制原始像素图的长宽比是否保留以及如何保留。
需要注意的是原生图像的缩放版本是缓冲的,所以不必担心性能的损失(除非视口尺寸不断变化)

void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode)

如果使能了视图口的背景pixmap的缩放(setBackgroundScaled),使用这个函数来定义是否和如何展示原生pixmap的缩放比例

void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElement & antialiasedElements)

设置哪些元素是强制作为QCP::AntialiasedElement的集合来反锯齿绘制的
这将覆盖所有元素组的抗锯齿设置,通常使用setAntialiasing函数来进行单个的控制,如果一个元素从来没有指定为 setAntialiasedElement 或者 setNotAntialiasedElements,那么反锯齿设置将会使用在每一个单元中。
举个例子,如果抗锯齿的单元包含 QCP::aePlottables,所有的绘图板将会进行反锯齿绘制,而无关指定的 QCPAbstractPlottable::setAntialiased值被设置
如果一个单元是抗锯齿的,然后设置了setNotAntialiasedEmelents,这将取消抗锯齿。

void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled = true)

设置是否指定antialiasedElement来强制平滑

void QCustomPlot::setNotAntialiaseElements(const QCP::AntialiasedElements & notAntialiasedElements)

设置哪一个元素强制关闭抗锯齿来作为一个或多个 Qt::AntialiasedElement的组合
这个覆盖了整个单元组的抗锯齿设置,通常使用函数setAntialiasing来对单个单元进行控制,如果一个单元从未指定为 setAntialiasedElements 或者 setNotAntialiasedElements,则抗锯齿设置在每一个单独的实例中会使用
举个例子,如果notANtilaliasedElements包含QCP::aePlottables,则没有绘图板将被抗锯齿绘制,无论QCPAbstractPlottable::setAntialiased的值设置成什么。
如果一个单元是 notAntialiasedElements的,设置了setAntilaliasedElements后将会移除前一个状态

void QCustomPlot::setNotAntialiasedElement(QCP::antialiasedElement notAntialiasedElement, bool enabled = true)

设置为不抗锯齿

void QCustomPlot::setAutoAddPlottableToLegend(bool on)

如果设置为true,那么如果在 CustomPlot 中添加一个绘图板的时候就会自动的添加一个图例

void QCustomPlot::setInteractions(const QCP::Interactions & interactions)

设置 CustomPlot 可能的交互为 QCP::Interaction 枚举的组合,这里有如下类型的交互:

  • 坐标轴范围的交互:Axis range manipulation 是由 QCP::iRangeDragQCP::iRangeZoom 所控制的,当各自的交互使能的时候,用户可以通过拖拽坐标轴和滑动滚轮的方式来缩放图像,详细的看如何控制坐标轴的方式请看 QCPAxisRect::setRangeDragQCPAxisRect::setRangeZoomQCPAxisRect::setRangeDragAxes, QCPAxisRect::setRangeZoomAxes
  • 绘图板的数据选择:Plottable data selection 是由 QCP::iSelectPlottables 所控制的,如果 QCP::isSelectPlottables 被设置了,用户可以选择绘图板(图像,曲线,柱状图)以及他们的数据,通过在他们附件点击他们(需要设置 setSelectionTolerance),无论用户是否真的选择了绘图表,其数据可以被 QCPAbstractPlottable::setSelecttable 方法所限制。详细的请看有关数据选择机制的页面,为了获取所有当前选中的绘图板的列表,调用函数 selectedPlottables,如果你仅仅对 QCPGraphs 感兴趣,你可能使用便利函数 selectedGraphs
  • 项目选择:Item selection是由 QCP::iSelectItems 所控制的,如果设置了 QCP::iSelectItems,用户可以选择项目(QCPItemLineQCPItemText 等)通过点击他们或者在他们的附近点击他们,为了找出是否指定的项目被选中了,可以调用函数 QCPAbstractItem::selected(),为了检索所有当前选中项目的列表,调用 selectedItems
  • 坐标轴选择:Axis selection 是由 QCP::iSelectAxes 所控制的,如果设置了 QCP::iSelectAxes 用户可以通过点击坐标轴来选中他们,哪些部分被选中(比如 Axis base line, tick labels, axis label)可以通过每一个坐标轴的QCPAxis::setSelectableParts 选项来判断。为了检索当前所包含的选中部分的列表,调用 selectedAxes,坐标轴的哪一个部分被选中可以通过 **QCPAxis::selectedParts()**来判断
  • 图例选择:Legend selection是由 QCP::iSelectAxes来控制的,如果设置了这个,用户可以选择图例或图例中单独的项目通过点击他们,哪个部分实际是可以选择的可以通过QCPLegend::setSelectableParts来控制,为了找出图例或者其内部的任何项目是选中的,检查QCPLegend::selectedParts的值,为了找出哪些子项目被选中了,调用QCPLegend::selectedItems
  • 所有其他项目的选择:All other selectable element,所有其他项目的选择(比如 QCPTextElement,或者自己派生的图层的子类)是由QCP::iSelectOther控制的,如果设置了,用户可以通过点击他们来选择他们,为了找出哪些现在被选择了,你需要去显式的检查他们选中的状态。

如果选中状态被用户的操作交互所改变了,则信号 selectionChangedByUser被发射,每一个选中的对象除此之外还会发射一个单独的选中改变的信号无论他们的选中状态是否改变,比如不是通过用户的交互所触发的。
为了允许多重对象被选择,通过保持选择修饰(MultiSelectModifier),设置flag为QCP::iMultiSelect

void QCustomPlot::setInteraction(const QCP::Interaction & interaction, bool enabled = true)

设置这个CustomPlot的单一的交互为使能
详细的关于交互系统,看setInteractions

void QCustomPlot::setSelectionTolerance(int pixels)

设置用来决定选中对象的像素容忍度
如果用户在曲线的附近点击了,比如QCPGraph,只有当点击位置与图形线之间的最小距离小于像素时,才认为是潜在的选择。对于一个区域定义的对象,比如QCPBars,仅仅需要点击区域内部,换句话说,只有那些很细的对象,不好选的,需要容忍度

void QCustomPlot::setNoAntialiasingOnDrag(bool enabled)

设置当用户拖拽坐标轴范围的时候,QCustomPlot是否禁用抗锯齿,如果很多对象,尤其是绘图板,是抗锯齿绘制的,这将在拖拽的时候显著的提升性能,这样它创建了更好的使用体验,当用户停止拖拽时,最后一次的重绘将会撑场抗锯齿,来获得更加高的视图质量

void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints)

设置CustomPlot实例的绘制提示为QCP::PlottingHint的集合

void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled = true)

设置开启绘制提示

void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier)

设置键盘辅助键为多重选择辅助键
如果QCP::iMultiSelect指定在设置交互中,用户可能需要在按下这个辅助键后一个接一个的点击选择的项目。
默认情况下多重选择辅助键设置成Qt::ControlModifier

void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode)

设置QCustomPlot进行鼠标点击和拖拽动作的动作
如果模式是QCP::srmNone,鼠标的拖拽转发到最下层的对象,举个例子,QCPAxisRect会在鼠标拖拽坐标轴范围的时候执行鼠标拖拽,看QCPAxisRect::setRangeDrag。如果模式不是设置为QCP::srmNone,当前选中的矩形将会激活并且允许比如矩形缩放和数据点选择。
如果你希望提供你的用户所有的坐标轴范围拖拽和数据选择/范围缩放的动作,使用这个方式来在交互进行后切换模式,比如,通过发射鼠标按下和移动的信号,举个例子,你可能需要检查是否用户正在保持按下键盘辅助键,并且决定应该设置哪个模式。
如果一个选中矩形交互被激活了,并且模式设置为了QCP::srmNone,交互取消了,切换任何其他的模式将会保持选中的区域激活,交互完成后,行为由当前设置模式定义,而不是交互开始时设置的模式。

void QCustomPlot::setSelectionRect(QCPSelectionRect * selectionRect)

设置QCPSelectionRect实例,如果模式不是QCP::srmNone且用户执行了点击拖拽交互动作,QCustomPlot使用这个实例。QCustomPlot有这个过去的selectionRect的所有权,它后面可以通过selectionRect来访问。
这个机制是很有用的,如果你希望使用QCPSelectionRect的子类实例来替换默认的QCPSelectionRect

void QCustomPlot::setOpenGl(bool enabled, int multisampling = 16)

警告:
这个现在还是一个试验中的特性,其特性取决于所运行的操作系统,有多个QCustomPlot的窗体是一个使能OpenGl的应用程序,其渲染可能导致某些系统冲突
这个方法将允许OpenGL来绘制渲染,目的是提高渲染的性能以生动的表达图形
如果使能了true,QCustomPlot将尝试初始化OpenGL,如果成功的话,将会开启硬件的持续加速,参数multisampling控制者每一次渲染将会采样多少次,本质上是控制抗锯齿的质量,如果多重采样设置的太高而硬件不支持,则会设置成最高允许值
你可以测试是否切换成OpenGL渲染模式,通过函数**QCustomPlot::openGl()**是否返回true,如果OpenGL初始化失败了,渲染将会持续使用软件光栅化,并且发出qDubug的警告
如果切换成OpenGL成功了,这个方法将会禁用标签缓存(setPlottingHint(QCP)),并且会将CustomPlot的抗锯齿设置覆盖所有的组件(setAntialiasedElements(QCP::aeAll)),实现高质量的输出,抗锯齿覆盖允许OpenGL绘制设备的像素对其。正如之前提到的,在OpenGL渲染实际的抗锯齿绘制是由多重采样来控制的,如果设置使能状态为false,反锯齿/标签缓存设置恢复到启用OpenGL之前的状态,如果在此期间没有改变的话。

注意:
OpenGL只有在定义了宏QCUSTOMPLOT_USE_OPENGL后才会编译,这个宏定义必须在包含QCustomPlot头文件之前设置,还需要在qmake的项目文件中定义**+= QCUSTOMPLOT_USE_OPENGL**

QCPAbstractPlottable * QCustomPlot::plottable(int index)

根据index返回绘图板,如果index为invalid,则返回0
这是这个函数的重载版本,这个函数是QCustomPlot::plottable(),如果没有参数就返回最后添加的plottable

QCPAbstractPlottable * QCustomPlot::plottable

这是一个重载函数
返回最后添加的绘图板

bool QCustomPlot::removePlottable(QCPAbstractPlottable * plottable)

从图表中移除指定的绘图板,如果必要的话,相关的图例项目也会被移除

bool QCustomPlot::removePlottable(int index)

这是一个重载函数
通过绘图板索引移除相应的绘图板

int QCustomPlot::clearPlottables()

从图表中移除所有的绘图板,相关的图例项目也会被移除

int QCustomPlot::PlottableCount() const

返回当前存在的绘图板

QList<QCPAbstractPlottable *> QCustomPlot::selectedPlottables() const

返回选中的绘图板的列表,如果没有绘图板选中了,这个列表为空
有一个便利函数,如果你仅仅对选中的图像感兴趣,看selectedGraphs

QCPAbstractPlottable * QCustomPlot::plottableAt(const QPointF & pos, bool onlySelectable = false) const

返回在像素点位置pos处的绘图板,绘图板仅仅包含一根线(类似于图像)在他们周围有一个容忍度,详细的请看SelectionTolerance,如果有多个绘图板需要考虑,离Pos最近的将先考虑
如果没有,就返回0

bool QCustomPlot::hasPlottable(QCPAbstractPlottable* plottable) const

返回这个QCustomPlot实例是否包含绘图板

QCPGraph * QCustomPlot::graph(int index) const

根据给定的index返回图像,如果index无效,则返回0

QCPGraph * QCustomPlot::grap() const

返回最近添加的Graph

QCPGraph * QCustomPlot::addGraph(QCPAxis * keyAxis = 0, QCPAxis * valueAxis = 0)

在plot中创建一个新的图像,如果keyAxis和valueAxis是左边未定义(0),下方(xAxis)用作键,左边(yAxis)用作值,如果指定了,键轴和值轴必须属于QCustomPlot
并且返回指向新创建的图像的指针,如果图像创建失败就返回0

bool QCustomPlot::removeGraph(QCPGraph * graph)

从plot中移除指定的图像并且删除它,如果有必要的话,相关的图例也会移除,如果在plot中任何其他的图像具有指向已删除图的通道填充设置,这些通道填充的属性将被设置为0

bool QCustomPlot::removeGraph(int index)

这是一个重载函数,通过index来移除和删除图像

int QCustomPlot::clearGraphs()

从plot中移除所有的图像,相关的图例也会移除

int QCustomPlot::graphCount() const

返回当前在plot中存在的图像的数量

QList<QCPGraph *> QCCustomPlot::selectedGraphs() const

返回选中的图像的列表,如果当前没有图像被选中这个列表为空
如果对图像不感兴趣,而是要看其他的绘图板,比如QCPCurve,QCPBars,使用selectedPlottables

QCPAbstractItem * QCustomPlot::item(int index) const

根据Index返回项目

QCPAbstractItem * QCustomPlot::item() const

这是一个重载函数
返回最后一个添加进plot中的项目

bool QCustomPlot::removeItem(QCPAbstractItem * item)

从指定的plot中移除指定的项目

boo QCustomPlot::removeItem(int index)

根据Index移除项目

int QCustomPlot::clearItems()

移除Plot中的所有的项目

int QCustomPlot::itemCount() const

返回当前存在于plot中的项目的数量

QList<QCPAbstractitem *> QCustomPlot::selectedItems() const

返回当前选中的项目的列表

QCPAbstractItem * QCustomPlot::itemAt(const QPointF & pos, bool onlySelectable = false) const

在像素点的位置pos返回项目,在项目仅为一条线的时候考虑容忍度,多个项目在容忍度内部,仅仅返回离线最近的

bool QCustomPlot::hasItem(QCPAbstractItem * item) const

返回是否有这个项目

QCPLayer * QCustomPlot::layer(const QString & name) const

通过制定的名称返回图层,如果指定的名字没图层则返回0

QCPLayer * QCustomPlot::layer(int index) const

通过index返回图层

QCPLayer * QCustomPlot::currentLayer() const

返回设置为当前图层的图层

bool QCustomPlot::setCurrentLayer(const QString &name)

给当前的图层设置名字,所有的图层(QCPLayerable),比如绘图板和项目,都是在当前的图层中创建的,如果设置成功则返回true。

bool QCustomPlot::setCurrentLayer(QCPLayer * layer)

设置当前的图层为给定的图层

int QCustomPlot::layerCount() const

返回当前plot中存在的视图的数量

bool QCustomPlot::addLayer(const QString & name, QCPLayer * otherLayer = 0, QCustomPlot::layInsertMode insertMode = limAbove)

在QCustomPlot实例中添加一个新的图层,新的图层将设置为name,必须是独一无二的,还取决于insertMode,可以设置为向上添加还是向下添加。

bool QCustomPlot::removeLayer(QCPLayer * layer)

移除指定的视图

bool QCustomPlot::moveLayer(QCPLayer * layer, QCPLayer * otherLayer, QCustomPlot::LayerInsertMode insertMode = limAbove)

将layer移动到otherLayer的上方或下方,上方还是下方是由insertMode决定的

int QCustomPlot::axisRectCount() const

返回plot中轴矩形的数量

QCPAxisRect * QCustomPlot::axisRect(int index = 0) const

根据索引返回轴矩形

QList<QCPAxisRect *> QCstomPlot::axisRects() const>

返回当前Plot中的所有的轴矩形

QCPLayoutElement * QCustomPlot::layoutElementAt(const QPointF & pos) const

返回像素点处的布局单元,如果在像素点处没有单元,返回0

QCPAxisRect * QCustomPlot::axisRectAt(const QPointF & pos) const

返回像素点处的QCPAxisRect类型的布局单元,此方法忽略其他布局元素,即使它们在轴矩形前面(例如QCPLegend)。如果不存在轴矩形,返回0
只有有效的轴矩形可以使用

void QCustomPlot::recaleAxes(bool onlyVisiblePlottables = false)

重新调整坐标轴,使图中的所有绘图项(如图形)都完全可见。
如果onlyVisiblePlottables设置为真,只有设置为真的绘图板将会用来重新调整坐标轴

QList<QCPAxis *> QCustomPlot::selectedAxes() const

返回当前选中的部分的坐标轴的列表

QList<QCPLegend *> QCustomPlot::selectedLegends() const

返回选中部分的图例的列表,也就是选中状态不是QCPLegend::spNone

void QCustomPlot::deselectAll()

放弃QCustomPlot中的所有的绘图板
因为调用这个函数不是用户的交互,它不会发射信号selectionChangendByUser信号,个体的选中状态的变化信号已经足够了,如果这个对象之前被选中了。

//下面是一些保存至图像PDF的函数,到时候用的时候再看吧

void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority = QCustomPlot::reRereshHint)

造成完成的重绘到内部的绘制缓存区,最后,窗体的表面将会刷新为新的缓存内容,这是一定在plot发生改变的过程,比如在轴上的范围或图形的数据点是可见的。
参数刷新优先级refreshPriority可以用来调整重绘的时间,举个例子,如果你的应用程序调用重绘函数非常的频繁,(比如多个独立函数更改了绘图的某些方面,每个函数都希望确保重新绘制了更改)好的方法是设置刷新优先级为QCustomPlot::reQueuedReplot,这种方式下,实际的重绘将会延迟到下一个事件循环中,这样的话,多个连续的调用的重绘将仅仅造成一次重绘,避免了冗余重绘并且提高了性能。
在极少数情况下,QCustomPlot会自己重绘自己,这些是QCustomPlot调整大小的事件和用户交互(对象选择和范围的拖拽缩放)
在重绘发生之前,将会发射信号beforeReplot,在重绘之后,会发射afterRepot信号,将这个信号手动的连接到槽函数是安全的,可以将两个QCustomPlot的信号和槽连接在一起,保证两个的重绘是同步的,不会造成无限递归

void QCustomPlot::mouseDoubleClick(QMouseEvent * event) [signal]

这个信号将会发射当鼠标双击的时候

void QCustomPlot::mousePress(QMouseEvent * event) [signal]

这个信号将在鼠标按下的时候发射
它在QCustomPlot处理任何其他机制(如范围拖动)之前发出,因此,连接到这个信号的插槽仍然可以影响行为,例如,使用QCPAxisRect::setRangeDrag或QCPAxisRect::setRangeDragAxes。

void QCustomPlot::mouseMove(QMouseEvent* event) [signal]

这个信号将会在QCustomPlot接收到鼠标移动事件的时候发出
它在QCustomPlot处理任何其他机制(如范围拖动)之前发出。因此,连接到这个信号的插槽仍然可以影响行为,例如,使用QCPAxisRect::setRangeDrag或QCPAxisRect::setRangeDragAxes。
警告
这里不建议使用QCPAxisRect::setRangeDragAxes来更改拖动轴,因为在按下鼠标的那一刻,拖动起点就被保存了。因此,它只对当时设置的范围拖动轴有意义。如果您想要更改拖动轴,请考虑在mousePress信号中执行此操作。

void QCustomPlot::mouseRelease(QMouseEvent * event)

这个信号将会在QCustomPlot接收到一个鼠标释放的事件后发出。
它在QCustomPlot处理任何其他机制(如对象选择)之前发出。因此,连接到该信号的插槽仍然可以影响行为,例如,使用setinteraction或QCPAbstractPlottable::setSelectable。

void QCustomPlot::mouseWheel(QWheelEvent * event) [signal]

这个信号将在QCustomPlot接收到鼠标滚轮事件后发出
它在QCustomPlot处理任何其他机制(如范围缩放)之前发出。因此,连接到这个信号的插槽仍然可以影响行为,例如,使用QCPAxisRect:: setrangezoomoom, QCPAxisRect::setRangeZoomAxes或QCPAxisRect::setRangeZoomFactor。

void QCustomPlot::plottableClick(QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent * event) [signal]

这个信号将会在一个绘图板点击的时候发射
event是鼠标事件,造成点击的事件,plottable是接收到这个点击的绘图板,参数dataIndex指明了最靠近鼠标点击位置的数据点

void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable * plottable, int dataIndex, QMouseEvent* event) [signal]

这个信号将会在一个绘图板点击的时候发射
event是鼠标事件,造成点击的事件,plottable是接收到这个点击的绘图板,参数dataIndex指明了最靠近鼠标点击位置的数据点

void QCustomPlot::itemClick(QABStractItem * item, QMouseEvent* event) [signal]

当项目被点击的时候发射这个信号
event是鼠标事件,造成了item的点击,然后收到了这个点击

void QCustomPlot::itemDoubleClick(QCPAbstractItem * item, QMouseEvent * event) [signal]

当项目被双击的时候发射这个信号

void QCustomPlot::axisClick(QCPAxis * axis, QCPAxis::SelectablePart part, QMouseEvent* event) [signal]

当坐标轴点击的时候发射这个信号

void QCustomPlot::axisDoubleClick(QCPAxis * axis, QCPAxis::SelectablePart part, QMouseEvent * event) [signal]

这个信号当坐标轴双击的时候发射
event是双击的鼠标事件,axis是所双击的坐标轴,part是坐标轴所点击的地方

void QCustomPlot::legendClick(QCPLegend * legend, QCPAbstractLegendItem * item, QMouseEvent * event) [signal]

这个信号在图例点击的时候被发射
event是鼠标事件,legend是接收到鼠标点击的图例,item是图例中点击的项目,如果只有图例被点击了,item就为0,这在点击到两个item中间的时候发生

void QCustomPlot::legendDoubleClick ( QCPLegend * legend, QCPAbstractLegendItem * item, QMouseEvent * event) [signal]

图例双击的信号

void QCustomPlot::selectionChangedByUser() [signal]

这个信号在用户在QCustomPlot中改变了做选择的区域的时候发射,比如,用户点击了别的地方,当通过直接调用对象上的setSelected()/setSelection()或deselectAll来以编程方式更改对象的选择状态时,它不会发出。
在这个信号之外,选中的对象同样提供了单一的信号,举个例子,QCPAxis::selectionChanged或QCPAbstractplottable::selectionChanged,需要注意的是,这些信号即使在以编程的方式改变选中状态的时候也会发出。

void QCustomPlot::beforeReplot() [signal]

这个信号在plot重绘前发出

void QCustomPlot::afterReplot() [signal]

这个信号在plot重绘后发出

QSize QCustomPlot::minimumSizeHint() const [protected virtual]

这个函数根据顶层布局的最小尺寸返回最小尺寸的提示,为了防止QCustomPlot折叠为大小/宽度为0,可以在整个QCustomPlot上或在其中的任何布局元素上设置最小大小(setMinimumSize),这一点尤其重要,当放置在QLayout中,而其他组件试图占据尽可能多的空间时(例如QMdiArea)。

QSize QCustomPlot::sizeHint() const [protected virtual]

返回和minimumSizeHint一样的尺寸提示

void QCustomPlot::paintEvent(QPaintEvent * event) [protected virtual]

当QCustomPlot小部件需要重新绘制时的事件处理程序。这不会导致重绘,而是在小部件表面绘制内部缓冲区。

void QCustomPlot::resizeEvent(QResizeEvent * event) [protected virtual]

QCustomPlot窗体的事件处理程序,视图口(现在成为mPlotLayout的外部矩形)将会适当的调整,最后执行重绘动作。

void QCustomPlot::mouseDoubleClickEvent(QMouseEvent * event) [protected virtual]

当双击发生的时候的事件处理程序,发射鼠标双击的信号,然后,然后确定游标下的可分层对象,并将事件转发给它。最后,当确定了点击的对象后,发射指定的信号(比如plottableDoubleClick, axisDoubleClick)

void QCustomPlot::mousePressEvent(QMouseEvent * event) [proticted virtual]

当单击事件发生后的事件处理程序,发射鼠标单击的信号。
如果当前的setSelectionRectMode不是QCP::srmNone,将会滤过所选中的矩形,否则,确定游标下的可分层对象,并将事件转发给它。

void QCustomPlot::mouseMoveEvent(QMouseEvent * event) [protected virtual]

当光标移动的时候的事件处理程序,发射鼠标移动的信号。
如果选中矩形(setSelectionRect)当前激活了,事件将会转发来更新矩形形状。
否则,如果布局单元有鼠标捕获焦点(在之前的顶层布局元素发生了鼠标点击事件),那么鼠标移动时间将会转发给那个单元。

void QCustomPlot::mouseReleaseEvent(QMouseEvent * event) [protected virtual]

当鼠标按键释放的时候,阿舍鼠标释放的信号。
如果自mousePressEvent以来,鼠标移动的方向小于某个阈值。它被认为是导致选择机制(如果通过setinteraction激活)相应改变选择状态的点击,更多的是,指定了鼠标点击的信号被发射。
如果一个层事件是鼠标的捕获者(之前发生在层事件之上的鼠标按压事件),则mouseReleaseEvent被转发到该元素。

void QCustomPlot::wheelEvent(QWheelEvent * event) [protected virtual]

鼠标滚轮事件的发生的事件过滤器,首先会发射鼠标滚轮信号,然后确定影响的布局并且将事件传递给他们。

void QCustomPlot::draw(QCPPainter * painter) [protected virtual]

绘制整个plot的函数,包括背景pixmap,使用指定的painter,它不像replot一样使用绘制缓存,所以这个函数典型的通过保存/导出方法就像sacePdf
需要注意的是,它不会使用背景刷来填充背景,作为用户需要指定函数setBackground(const QBrush &brush),这取决于调用此方法的各个函数。

void QCustomPlot::updateLayout() [protected virutal]

执行由QCPLayoutElement::UpdatePhase中定义的布局更新步骤,通过调用QCPlayoutElement::update函数在主绘制图层中,在这里,布局单元计算他们的位置和边缘,并且准备下面的draw函数调用。

void QCustomPlot::legendRemoved(QCPLegend * legend) [protected virtual]

这个方法是通过QCPLegend析构函数来使用的,向QCustomPlot报告图例删除,以便它可以相应地清除其QCustomPlot::legend成员。

void QCustomPlot::processRectSelection(QRect rect, QMouseEvent * event) [protected virtual]

此槽函数连接到了所选择矩形的QCPSelectionRect::accepted信号中,当setSelectionRectMode被设置为QCP::srmSelect的时候。
首先,它将通过选择的起点来确定哪一个坐标轴rect是选择rect的起点,然后它将遍历与此坐标轴所有关联的绘图板(准确的说是QCPAbstractPlottable1D)来找出哪些数据点在矩形中,它通过查询他们的QCPAbstractPlottable1D::selectTestRect方法来实现。
然后,实际选择的区域是通过调用绘图板的QCPAbstractPlottable来实现的,将找到的选定数据点作为QVariant(QCPDataSelection)放在details参数中,所有未被rect触及的绘图板将收到QCPAbstractPlottable::deselectEvent。

void QCustomPlot::processRectZoom(QRect rect, QMouseEvent* event) [protected virtual]

这个槽函数连接到了所选择矩形中的QCPSelectionRect::accepted信号中,当setSelectionRectMode设置为**QCP::srmZoom的时候。
它通过所选区域的起始点来确定了哪个坐标轴矩形是原始的选择矩形,然后缩放由QCPAxisRect::setRangeZoomAxes所定义的矩形。

void QCustomPlot::processPointSelection(QMouseEvent * event) [protected virtual]

这个方法在简单的左键点击的时候会调用,发现在QCustomPlot的表面。
他首先确定点击的图层,然后调用它的QCPLayerable::selectEvent,所有其他的图层收到一个QCPLayerable::deselectEvent(除非多重选择辅助键被按下)
在该方法中,使用layerableAt(在鼠标点击事件后)来二次确定选中的图层,因为我们想onlySelectable在这次设置为true,这意味着鼠标事件获取器(mMouseEventLayerable)可能和这里所点击的图层不同,举个例子,前面的图层将会收到鼠标事件,但是在后面的选中的项目将会收到QCPLayable::selectEvent

bool QCustomPlot::registerPlottable(QCPAbstractPlottable * plottable) [protected]

将制定的绘图板注册到这QCustomPlot中,并且,如果使能了setAutoAddPlottableToLegend后,会将其加到图例中,QCustomPlot有此绘图板的所有权。
如果成功了就返回true,当绘图板不存在于父项plot中时,其父项为QCustomPlot。
这个方法会在QCPAbstractPlottable的基构造函数中自动调用。

bool QCustomPlot::registerGraph(QCPGraph * graph) [protected]

为了维持QCustomPlot中的简单的图像接口,这个方法在QCPGraph的构造函数中会自动的调用,将其注册到QCustomPlot内部的图像列表中,如果成功就返回true,如果图像有效,但是没有在CustomPlot中,那么其父项是QCustomPlot。
这个图像指定的注册发生在QCPAbstractPlottable的基类调用registerPlottable中。

bool QCustomPlot::registerItem(QCPAbstractItem * item) [protected]

将制定的项目注册到这个QCustomPlot中,QCustomPlot对其拥有所有权
如果成功就返回true,比如项目已经存在但是其父项是QCustomPlot
这个方法在QCPAbstractItem基类构造函数中自动调用

void QCustomPlot::updateLayerIndices() const [protected]

指派所有的图层的索引到mLayers列表中,因此,在每次改变层索引的操作之后,如层移除、层创建、层移动,都会调用此方法。

QCPLayerable * QCustomPlot::layerableAt(const QPintF & pos, bool onlySelectable, QVariant * selectionDetails = 0) const [protected]

返回像素点pos处的最顶层的图层项目,如果onlySelectable设置为true,那么只会考虑选中的项目(图层项目的子类通过QCPLayerable::selectTest方法来和他们的selectability通信)
selectionDetails是一个输出参数,包含受影响分层的选择细节。如果相应的分层可被赋予一个后续的QCPLayerable::selectEvent(类似于mouseReleaseEvent),那么这就很有用了。selectionDetails在多方图层项目中(比如QCPAxis::SelectablePart)通常包含关于可分层的哪一部分被命中的信息.如果图层项目是一个绘图板,selectionDetails会包含一个QCPDataSelection的实例,包含一个离像素点最近的数据点。

QList<QCPLayerable *> QCustomPlot::layerablelistAt(const QPonitF & pos, bool onlySelectable, QList<QVariant> * selectionDetails = 0) const [protected]

返回在像素点pos处的图层项目,如果onlySelectable设置为true,那么只有那些选中的图层项目将会选中
返回列表的排序是通过图层项目/绘制绘制顺序所决定的,如果你仅仅需要知道最顶层的图层项目,请使用layerableAt.

void QCsutomPlot::drawBackground(QCPPainter * painter) [protected]

绘制plot的视图口的背景pixmap
如果pixmap是由setBackground所提供的的,此函数根据setBackgroundScaled和setBackgroundMode来缩放缓存,然后使用提供的painter在视图口中绘制。缩放版本缓存了mSacledBackgroundPixmap的方式重绘每一次缩放,这仅仅是更新,当坐标轴矩形改变了缩放背景pixmap的方式(取决于setBackgroundScaledMode),或者当设置不同的pixmap的时候。

void QCusttomPlot::setupPaintButters() [protected]
QCPAbstractPaintBuffer * QCustomPlot::createPaintBuffer() [protected]
bool QCustomPlot::hasInvalidatedPaintBuffers() [protected]
bool QCustomPlot::setupOpenGl() [protected]
void QCustomPlot::freeOpenGl() [protected]

2.6.2 Field Documentation字段文档

QCPAxis * QCustomPlot::xAxis

一个指向Plot轴矩形的下方的主要的x轴
QCustomPlot提供了便利的指向坐标轴的指针(xAxis, yAxis, xAxis2, yAxis)和其图例。这让其非常方便的如果Plots仅仅有一个坐标轴矩形的时候,并且在一遍最多只有一个坐标轴,如果你使用布局系统来在一边添加多个坐标轴矩形或者多个坐标轴,使用QCPAxisRect::axis接口来访问新的坐标轴,如果4个默认的坐标轴的默认图例通过布局系统来移除了(比如移除了主坐标轴矩形),则相关的指针将会变为0
如果一个坐标轴的便利指针是0,并且一个新的坐标轴矩形或者一个先关的坐标轴添加到主坐标轴矩形中,QCustomPlot会根据新的坐标轴重设置这个便利指针,这很像图例边界指针在一个图例在主图例删除后添加进来后将会被重设置。
//下面的3个坐标轴和默认图例相同

3 介绍和QCustomPlot核心类相关的几个类

在这里插入图片描述

3.1 QCPLayer

一个layer可以包含很多对象,来控制渲染的顺序

3.1.1 Detailed Description 详细描述

一个layer可以包含很多对象,来控制渲染的顺序
QCustomPlot的图层系统的机制是来控制Plot中单元的渲染顺序
它基于两个类QCPLayer和QCPLayerable,QCustomPlot内部有一个或多个QCPLayer(看 QCustomPlot::addLayer,QCustomPlot::layer,QCustomPlot::moveLayer等)的渲染列表,当重绘的时候,QCustomPlot会从下到上的遍历这layer的列表,并相继的将这些图层中的layerables绘制到绘图缓存中。
一个QCPLayer包含一个QCPLayerable实例的顺序,QCPLayerable是一个基本上所有的可见项目的虚基类

3.1.2 Default layers 默认图层

最初的时候QCustomPlot有6个图层,“背景background”,“网格grid”,“主main”,“坐标轴axes”,“图例legend”和“覆盖(暂时先这么叫吧)overlay”。最顶层的是“overlay”图层,在其中仅仅包含QCustomPlot的矩形选择(QCustomPlot::selectionRect),下面的两个图层是“坐标轴”和“图例”,包含了默认的坐标轴和图例,所以他们将会在绘图板上面绘制,在中间,是“主main”图层,它最初是空的,并且设置作为当前的图层(看QCustomPlot::setCurrentLayer),这意味着所有的新的绘图板,项目等,默认情况下都在这个图层上绘制,然后下面的是“网格”图层,其中包含了QCPGrid的实例(严格属于QCPAxis,详细的请看QCPAxis::grid),坐标轴矩形背景会隐藏在所有的东西的后面,因此默认的QCPAxisRect实例将会放置在“背景background”图层中,当然,单个对象的图层的从属关系可以根据需要改变(QCPLayerable::setLayer)。

3.1.3 Controlling the rendering order via layer 根据图层来控制渲染顺序

控制图层的渲染顺序是很简单的,在你希望的layerable所处的位置创建新的图层,使用QCustomPlot::addLayer,然后使用函数QCustomPlot::setCurrentLayer设置当前的图层,并且正常的创建对象,他们将会根据当前的图层设置自动的放置在新的图层上。另一种方式是你也可以忽略当前的图层设置,仅仅通过QCPlayerable::setLayer来在创建新的对象后移动其到期望的图层中。
移动整个图层也是可以的,举个例子,如果你希望网格在“main”图层中的所有其他项目之前显示,使用QCustomPlot::moveLayer到“main”图层前面。
在同一图层中渲染的顺序也是很简单的,通过创建或插入的顺序,最后创建的项目(或者最后添加到图层的项目)将会在本图层的所有的其他项目之前绘制。
当图层被删除后,里面的对象不会删除,而是掉落在已经删除的图层的下面的图层,看QCustomPlot::removeLayer。

3.1.4 Replotting only a specific layer 仅仅重绘一个指定的图层

如果图层的模式(setMode)被设置为ImBuffered(自己有独立的绘图缓存),你可以通过对这一个图层调用重绘函数,在特定的情况下项目重绘所有的图层,它可以提供更好的重绘性能。在创建新的图层后,这个图层的模式是ImLogical(和其他图层公用缓存)。

3.2 QCPLayer[abstract]

这是绝大多数的看得见的对象的基类
在这里插入图片描述

3.2.1 Detailed Description 详细描述

这是一个纯虚基类,绝大多数可见的对象都从中继承,比如plottables, axes, grid等
在图层中的所有的layerable允许通过堆叠顺序来控制渲染顺序

3.3 QCPAbstractItem[abstract]

QCPAbstractItem是Plot中所有的项目的基类
在这里插入图片描述

3.3.1 Detailed Description

在QCustomPlot中,项目是附加的图像单元类似于plottables(QCPAbstractPlottable),不像坐标轴(QCPAxis),虽然plottables总是和两个轴相绑定,因此可以绘制坐标轴,但是项目可以防止在绝对坐标轴,从而不受任何坐标轴的影响。每一个指定的项目至少有一个QCPItemPosition 成员用来控制其位置,一些项目是由两个坐标所决定的,因此它就有两个或更多的QCPItemPosition成员对象,比如QCPItemRect有左上角和右下角。
这个虚基类只定义了很简单的接口,比如可见性和裁剪性,因为这个类是抽象的,所以它不能实例化,使用它的子类或者自己创建子类
内置的子类项目是:

子类名称子类介绍
QCPItemLine由一个起点和一个终点所定义,可以有不同的风格(比如箭头)
QCPItemStraightLine一条由起始点和方向定义的直线,不像QCPItemLine,这个直线是无限长的,并且没有终点的
QCPItemCurve一条由起点,结束点,和两个中间控制点所构成的曲线,可以有不同的样式
QCPItemRect一个正方形
QCPItemElipse一个椭圆形
QCPItemPixmap一个任意的pixmap
QCPItemText一个文字标签
QCPItemBracket一个凸起,可以用来参考,高亮显示Plot中具体的部分
QCPItemTracer一个可以附加到QCPGraph上并粘着它的数据点的项,给定一个键坐标。

3.3.2 Clipping 裁剪

项目是默认裁剪到坐标轴矩形内(意思是只在坐标轴内部才能显示),为了使项目在坐标轴外部也可以显示,禁用裁剪选项,setClipToAxisRect(false)。
换句话说,如果你希望项目可以被裁剪到一个不同的坐标轴矩形中,通过setClipAxisRect来指定,项目的属性clipAxisRect仅仅用于裁剪行为,并且,在原则上,它独立于项目可能通过其位置成员绑定到的坐标轴(QCPItemPosition::setAxes)。然而,通常,用于剪切的轴矩形还包含用于项目位置的轴。

3.3.3 Using items 使用项目

首先需要创建一个实例,然后添加在plot中

QCPItemLine *line = new QCPItemLine(customPlot)

默认情况下,项目的位置是由plotd的X轴和Y轴绑定的,所以我们可以设置线开始的坐标来设置其位置

line->strat->setCoords(-0.1, 0.8);
line->end->setCoords(1.1, 0.2);

如果我们不希望这条线依附于Plot坐标系中,而是在一个不同的坐标系中比如绝对坐标系,我们需要像如下的方式来改变坐标系

line->start->setType(QCPItemPosition::ptAbsolute);
line->end->setType(QCPItemPosition::ptAbsolute);

然后我们可以设置坐标系了,这次是用像素的方式

line->start->setCoords(100, 200);
line->end->setCoords(450, 320);

然后让这根线在整个QCustomPlot中有效,通过禁用轴矩形的裁剪功能

line->setClipToAxisRect(false)

对于更复杂的Plots,甚至可以根据项目位置的X/Y坐标设置不同的类型和父锚点,使用QCPItemPositon::setTypeX或者QCPItemPosition::setParentAnchorX,详细的内容请看QCPItemPositionw文档

3.3.4 创建自己的项目

为了创建自己的项目,你需要实现QCPAbstractItem的子类,这里有几个纯虚函数,你可以来重写

  • selectTest
  • draw

详细的请看这些函数的文档

3.3.5 允许项目被定为

像之前所提到的,项目的位置是由QCPItemPosition的成员函数所确定的,让我们j假定新的项目只有一个点作为其位置,你可以添加一个pbulic的成员函数,类型是QCPItemPosition,如下:

QCPItemPosition * const myPosition;

const确定了这个指针在用户所创建的新的项目中是不可修改的,当然其所指向的QCPItemPositions实例是不可以被修改的,指针的初试话通过createrPosition函数很容易创建,仅仅在构造函数中将这个函数的返回值指定给在你的项目的每一个QCPItemPosition,createrPosition函数需要一个这个位置的名字,典型的情况是和这个变量名相同,一个QCPItemExample的构造函数看起来像这个样子

QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) :
	QCPAbstractItem(parentPlot),
	myPosition(createPosition("myPosition"))
	{
		//其他的构造函数的代码
	}

3.3.6 The draw function 绘制函数

为了给你的项目视觉上的呈现,重写draw函数并且使用过去的QCPPainter来绘制这个项目,你可以从位置成员QCPItemPosition::pixelPosition中检索到项目的像素坐标。
为了提高性能,你首先要计算边框矩形(不要忘记把笔的宽度考虑进去),检查其是否和边框矩形相交,并且在这种情况下将他们全绘制进去。

3.3.7 The selectTest funtion 选中测试函数

实现selectTest函数可以使用helper QCPVector2D::distanceSquaredToLine和rectDistance,对于大多数项目来说,选择测试的实现变得非常简单。有关函数参数的含义和函数应该返回的内容,请参阅selectTest的文档。

3.3.8 Providing anchors 提供锚点

提供锚(QCPItemAnchor)从添加位置开始。首先创建一个公共成员

QCPItemAnchor * const bottom;

并使用createAnchor函数在构造函数中创建它,为它分配一个名称和一个锚id(一个枚举项目上所有锚的整数,您可以为此创建一个自己的enum)。由于锚点可以放置在任何地方,相对于项目的位置,您的项目需要通过重新实现anchorPixelPosition(int anchorId)函数来提供每个锚点的位置。
本质上,QCPItemAnchor仅仅是一个中介,当连接到锚上的任何东西都需要知道坐标时,它会询问您的项目的像素位置。

3.4 QCPAbstractPlot

这个类是plot中所有显示的对象的虚基类
在这里插入图片描述

3.4.1 Detailed Description

它定义了非常基本的接口,比如名称,画笔,画刷,可见性等。因为这个类是纯抽象的,所以它不能被实例化。需要使用它的子类或者字节集创建子类,来实现自己显示数据的方式,Plottables可以显示一维的数据,基于模板类QCPAbstractPlottable1D。
下面的特性需要在创建子类的时候指定,举个例子。

  • 一个普通的用来显示一条线或者散点图的QCPGraph
  • 带参数的曲线QCPCurve
  • 柱状图QCPBars
  • 静态箱型图QCPStatisticalBox
  • 带颜色的等高线图,

Creating own plottables

直接从QCPAbstractPlottable中派生子类唯一建议的是希望像QCPColorMap那样显示二维的数据,比如两个键来确定一个值,如果你只想通过一个值来确定另外一个值建议从QCPAbstractPlottable1D中派生
如果直接从QCPAbstractplottable中创建子类,下面的虚函数需要实现

  • selectTest
  • draw
  • drawlegendIcon
  • getKeyRange
  • getValueRange

在绘制绘图时,可以使用coordsToPixels函数将绘图坐标中的点转换为像素坐标。这个函数非常方便,因为它考虑了键和值轴的方向(当键轴是垂直的而值轴是水平的时候,x和y被交换)。如果您担心性能(例如,您需要在一个循环中转换许多点,如QCPGraph),您可以直接使用QCPAxis::coordToPixel。但是,您必须自己考虑轴的方向。
下面是一些从这个类中派生出来的类

类名称类介绍
QCustomPlot *mParentPlot一个指向父项QCustomPlot实例的指针,父项plot是通过构造函数中的坐标轴推断出来的
QString mName这个plottable的名字
QPen mPen这个plottable的通用的pen,你应该使用这个pen在大多数的数据显示中,比如QCPGraph使用这个pen绘制图像的曲线和散点
QBrush mBrush这个Plottable通用的刷子,你可以使用这个刷子在大多数的需要在plottable中填充(比如QCPGraph使用这个刷子填充曲线和坐标轴之间的区域)
QPointer< QCPAxis > mKeyAxis, mValueAxis此plottable所需要依附的键值对,调用他们的QCPAxis::coordToPixel函数来将无论是键变化还是值变化的时候把坐标轴坐标转换为像素坐标,要确认是否这个点在使用之前是不是null,如果是null的话,将不会在Plottable中绘制
QCPSelectionDecorator mSelectionDecorator当前设置选择装饰器,它指定如何绘制和装饰所选的绘图表数据,在绘制数据时,在绘制未选中/选中的数据段之前,您必须咨询此装饰器以获得适当的钢笔/画笔。最后,您应该在绘制实现的最后调用它的QCPSelectionDecorator::drawDecoration方法
QCP::Selection Type mSelectable如果有的话,可以选择该绘图表的数据。对数据选择强制执行此设置是由QCPAbstractPlottable自动完成的
QCP::Selection Type mSelectable保存当前绘图表数据的选择状态,即选择的数据范围(QCPDataRange)。

3.5 QCPLayoutGrid

一个在网格中排列子项目的图层

3.5.1 Detailed Description

项目通过缩放延伸(setColumnStretchFactor, setRowStretchFactor)和间隔(setColumnSpacing, setRowSpacing)来确定布局。
项目可以通过addElement函数来添加到单元中,如果没有指定行或者列,网格将会延伸,单元中是否有一个有效的布局单元可以通过函数hasElement来检查,这个单元可以通过单元来检索,如果仅有空单元的行和列将会被移除,调用方式很简单,元素的删除可以通过将元素添加到不同的布局中或者使用QCPLayout接口take或remove来完成。
如果您使用addElement(QCPLayoutElement*)而没有显式的行和列参数,那么网格布局将根据当前的setFillOrder和换行(setWrap)选择位置。
可以使用insertRow和insertColumn插入行和列。

  • 12
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Qt5是一种流行的跨平台的图形用户界面(GUI)开发框架。而QCustomPlot则是一个基于Qt5的开源C++绘图库,用于在Qt应用程序中创建各种图表和绘图。它提供了丰富的功能和灵活的接口,可以满足实时绘制的需求。 要在Qt5应用程序中实现实时绘图,可以使用QCustomPlot库。首先,需要在Qt项目中引入QCustomPlot库的头文件和源文件,并在项目配置文件中添加相关的库依赖。 接下来,可以创建一个QWidget或QMainWindow的子类作为绘图窗口,然后在这个窗口中添加一个QCustomPlot对象。可以通过设置QCustomPlot对象的属性来自定义图表的样式和布局,例如坐标轴、图例、线条、图形等。 在实时绘图的过程中,可以通过调用QCustomPlot对象的函数来实时更新图表的数据。例如,可以使用addGraph()函数添加一个新的曲线图,然后使用graph()->setData()函数更新曲线图的数据。在每次更新后,可以使用replot()函数重新绘制图表。 为了实现实时绘图,可以使用定时器来定期更新数据并重新绘制图表。通过配合定时器和数据源,可以在实时绘图中显示不断变化的数据。 总结起来,使用Qt5和QCustomPlot库可以轻松实现实时绘图功能。只需要引入库文件、创建图表窗口和QCustomPlot对象,并设置图表样式和布局。然后,通过定时器不断更新数据并重新绘制图表,即可达到实时绘图的效果。这样可以轻松实现各种实时数据的可视化呈现。 ### 回答2: Qt是一种跨平台的C++应用程序开发框架,而QCustomPlot是一个基于Qt的图表绘制库。结合使用QtQCustomPlot,我们可以开发出实时更新的图表应用程序。 实时是指图表数据可以动态地更新,并且能够在数据更新时自动刷新显示。在Qt中,我们可以使用定时器来触发数据更新的操作,然后通过调用QCustomPlot的相关函数来更新图表。 首先,我们需要创建一个QCustomPlot的实例,并设置一些图表的基本属性,如标题、轴的标签等。然后,我们可以创建一个定时器,并将其与一个槽函数关联起来。在槽函数中,可以编写代码来更新图表的数据。这些数据可以来自于传感器、文件、网络等来源。一旦数据更新,在槽函数中我们可以调用QCustomPlot的相关函数来更新图表的显示。 具体来说,QCustomPlot提供了一系列函数来设置图表的数据和显示样式。例如,我们可以使用addGraph函数来添加一个曲线图层,使用setData函数来设置曲线的数据,使用rescaleAxes函数来自动调整轴的范围等等。 在定时器触发时,我们可以更新图表的数据,并通过重新绘制来刷新图表的显示。这可以通过调用replot函数来实现。 此外,QCustomPlot还提供了一些交互功能,如缩放、平移等,可以通过设置相应的参数来启用这些功能。 总的来说,通过组合使用QtQCustomPlot,我们可以很容易地实现实时更新的图表应用程序。在固定的时间间隔内更新数据,并通过QCustomPlot来实时显示更新后的数据,用户可以实时观察到数据的变化,从而更好地分析和理解数据。 ### 回答3: Qt5是一种用于开发跨平台应用程序的框架,QCustomPlot是一个能够提供实时绘图功能的插件。在使用Qt5和QCustomPlot实现实时功能时,需要进行以下步骤: 1. 首先,确保已经正确安装了Qt5和QCustomPlot库,并在项目中添加了相应的头文件和库文件。 2. 创建QCustomPlot对象,该对象将用于实时绘图。可以在主窗口或者自定义的绘图窗口中添加这个对象。 3. 设置绘图区域的参数,例如坐标轴的范围、网格线等。 4. 创建一个定时器,用于定时触发绘图更新操作。在定时器的槽函数中,可以调用QCustomPlot的相应函数进行数据的更新和绘图。 5. 在每次定时器触发时,更新数据并重新绘制图像。可以通过QCustomPlot的addGraph函数添加新的图层,并使用setData函数设置数据。 6. 当有新的数据添加到图层中时,调用replot函数重新绘制图像。 通过上述步骤,就可以实现使用Qt5和QCustomPlot进行实时绘图。在每次定时器触发时,更新数据并重新绘制图像,从而实现实时的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值