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插入行和列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章