Qwt源码解读之平移操作类

       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:
QwtPlotZoomerQwtPlotMagnifier
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 ); 设置伴随平移更新标尺刻度的轴。默认是平移时所有的轴都会被更新刻度。




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值