Qwt源碼解讀之平移操作類

來源:互聯網
上載者:User

       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 ); 設定伴隨平移更新尺規刻度的軸。預設是平移時所有的軸都會被更新刻度。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.