Qwt 提供了對圖形組件的平移操作,其實就是在平移時,通過將圖形繪製在另一個組件(QWidget)上實現了平移的效果(抓取)。這一切都是通過Qt的事件機制實現的。
QwtPanner類:提供平移操作,像QRubberBand一樣,其也是QWidget的子類。QwtPanner類被QwtPlotPanner類繼承,用於對QwtPlotCanvas進行平移操作。繼承關係如所示:
先看一看Qwt文檔對QwtPanner類的說明:
QwtPanner provides
panning of a widget.
QwtPanner grabs
the contents of a widget, that can be dragged in all directions. The offset between the start and the end position is emitted by the panned signal.
QwtPanner grabs
the content of the widget into a pixmap and moves the pixmap around, without
initiating any repaint events for the widget. Areas, that are not part of content are not painted while panning. This makes panning fast enough for widgets, where repaints are too slow for mouse movements.
For widgets, where repaints are very fast it might be better to implement panning manually by mapping mouse events into paint events.
程式碼分析:
一、QwtPanner類:
1、建構函式:
/*! Creates an panner that is enabled for the left mouse button. \param parent Parent widget to be panned*/QwtPanner::QwtPanner( QWidget *parent ): QWidget( parent ){ d_data = new PrivateData(); setAttribute( Qt::WA_TransparentForMouseEvents ); setAttribute( Qt::WA_NoSystemBackground ); setFocusPolicy( Qt::NoFocus ); hide(); // 預設將其隱藏 setEnabled( true );}
繼承自QWidget。預設情況下,將其隱藏。
2、安裝/卸載事件過濾器:
/*! \brief En/disable the panner When enabled is true an event filter is installed for the observed widget, otherwise the event filter is removed. \param on true or false \sa isEnabled(), eventFilter()*/void QwtPanner::setEnabled( bool on ){ if ( d_data->isEnabled != on ) { d_data->isEnabled = on; QWidget *w = parentWidget(); if ( w ) { if ( d_data->isEnabled ) { w->installEventFilter( this ); } else { w->removeEventFilter( this ); hide(); } } }}
QwtPanner定義的一對啟用/禁用平移功能的介面:
void setEnabled( bool ); bool isEnabled() const;
隱藏了(hide)其基類QWidget的槽函數介面:
bool isEnabled() const; bool isEnabledTo(QWidget*) const; bool isEnabledToTLW() const;public Q_SLOTS: void setEnabled(bool); void setDisabled(bool); void setWindowModified(bool);
不能不說是一個敗筆!其實換個函數名字就能夠避免,不知道作者是否有出於別的原因考慮?
3、事件過濾函數eventFilter(o, e)與QwtMagnifier類中的差不多,這裡就不貼代碼了。
4、看一下返回QwtPanner操縱組件的mask(面具)的位元影像函數:
/*! \brief Calculate a mask for the contents of the panned widget Sometimes only parts of the contents of a widget should be panned. F.e. for a widget with a styled background with rounded borders only the area inside of the border should be panned. \return An empty bitmap, indicating no mask*/QBitmap QwtPanner::contentsMask() const{ return QBitmap();}
它是一個虛函數,預設實現返回一個空的QBitmap,在QwtPlotPanner類中會被重新實現。
5、再看一下QwtPanner類的一個實現抓取( grab)功能的函數:
/*! Grab the widget into a pixmap.*/QPixmap QwtPanner::grab() const{ return QPixmap::grabWidget( parentWidget() );}
它是一個虛函數,在其子類中可根據需要重新實現。
二、QwtPlotPanner類:繼承自QwtPanner類。
Qwt文檔說明:
QwtPlotPanner provides
panning of a plot canvas.
QwtPlotPanner is
a panner for a QwtPlotCanvas, that adjusts the scales of the axes after dropping
the canvas on its new position.
Together with QwtPlotZoomer and QwtPlotMagnifier powerful
ways of navigating on a QwtPlot widget can be implemented easily.
-
Note:
-
The axes are not updated, while dragging the canvas
-
See also:
-
QwtPlotZoomer, QwtPlotMagnifier
1、屬性資料:
class QwtPlotPanner::PrivateData{public: PrivateData() { for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) isAxisEnabled[axis] = true; } bool isAxisEnabled[QwtPlot::axisCnt];};
用數組儲存哪些座標軸伴隨平移而更新座標刻度。在元素個數(即大小)一定的情行,數組優於vector。例如這裡選擇數組就是一個不錯的選擇。
2、建構函式:
/*! \brief Create a plot panner The panner is enabled for all axes \param canvas Plot canvas to pan, also the parent object \sa setAxisEnabled()*/QwtPlotPanner::QwtPlotPanner( QwtPlotCanvas *canvas ): QwtPanner( canvas ){ d_data = new PrivateData(); connect( this, SIGNAL( panned( int, int ) ), SLOT( moveCanvas( int, int ) ) );}
注意:傳入的參數是QwtPlotCanvas而非QwtPlot。
3、contentsMask() 函數的實現:
/*! Calculate a mask from the border mask of the canvas \sa QwtPlotCanvas::borderMask()*/QBitmap QwtPlotPanner::contentsMask() const{ if ( canvas() ) return canvas()->borderMask( size() ); return QwtPanner::contentsMask();}
4、可以通過 setAxisEnabled( int axis, bool on ); 設定伴隨平移更新尺規刻度的軸。預設是平移時所有的軸都會被更新刻度。