Qwt源码解读之拾取操作类(一)

Qwt提供了对图形的拾取操作。


QwtEventPattern类:Qwt事件模式的集合。QwtEventPattern为鼠标和键盘的输入引入了一个间接层。它们可以用不同的符号名称来表示,因此应用代码可以通过单独的设置映射关系进行配置。QwtEventPattern类在初始化时定义了鼠标键,键盘键对应Qt中鼠标和键盘枚举变量的映射关系。当然,我们也可以通过属性设置接口重新指定它们的对应关系。

QwtPicker类:继承自QwtEventPattern,提供了在一个部件(QWidget)上的选择(拾取)功能。

QwtPlotPicker类:继承自QwtPicker,是QwtPlotCanvas上量身定制的QwtPicker。

QwtPlotZoomer类:继承自QwtPlotPicker。QwtPlotZoomer类对一个Plot部件提供了缩放功能,并将每一个缩放状态保存至栈中,因此还可以随时撤销与恢复。

代码分析:

一、QwtEventPattern类:

QwtEventPattern类中定义了两个公有的嵌套类(也称嵌套类型,nested class):

    //! A pattern for mouse events
    class MousePattern
    {
    public:
        //! Constructor
        MousePattern( int btn = Qt::NoButton, int st = Qt::NoButton )
        {
            button = btn;
            state = st;
        }

        //! Button code
        int button;

        //! State
        int state;
    };

    //! A pattern for key events
    class KeyPattern
    {
    public:
        //! Constructor
        KeyPattern( int k = 0, int st = Qt::NoButton )
        {
            key = k;
            state = st;
        }

        //! Key code
        int key;

        //! State
        int state;
    };
因为该类型只在QwtEventPattern类中被用到,所以将其定义为QwtEventPattern的嵌套类。但又由于需要为这两个嵌套类定义全局的相等比较操作符函数,所以将它们定义为public访问权限。这样在全局作用域中就可以通过作用域限定符QwtEventPattern::对其进行引用。见下面代码:

//! Compare operator
inline bool operator==( QwtEventPattern::MousePattern b1,
    QwtEventPattern::MousePattern  b2 )
{
    return b1.button == b2.button && b1.state == b2.state;
}

//! Compare operator
inline bool operator==( QwtEventPattern::KeyPattern b1,
   QwtEventPattern::KeyPattern  b2 )
{
    return b1.key == b2.key && b1.state == b2.state;
}

二、QwtPicker类:

       QwtPicker类Qwt拾取机制中极为重要的一个类。Qwt文档对QwtPicker类有如下说明:

QwtPicker provides selections on a widget.

QwtPicker filters all enter, leave, mouse and keyboard events of a widget and translates them into an array of selected points.

The way how the points are collected depends on type of state machine that is connected to the picker. Qwt offers a couple of predefined state machines for selecting:

While these state machines cover the most common ways to collect points it is also possible to implement individual machines as well.

QwtPicker translates the picked points into a selection using the adjustedPoints method. adjustedPoints is intended to be reimplemented to fixup the selection according to application specific requirements. (F.e. when an application accepts rectangles of a fixed aspect ratio only.)

Optionally QwtPicker support the process of collecting points by a rubberband and tracker displaying a text for the current mouse position.

Example
#include <qwt_picker.h>
#include <qwt_picker_machine.h>

QwtPicker *picker = new QwtPicker(widget);
picker->setStateMachine(new QwtPickerDragRectMachine);
picker->setTrackerMode(QwtPicker::ActiveOnly);
picker->setRubberBand(QwtPicker::RectRubberBand); 

The state machine triggers the following commands:

  • begin()
    Activate/Initialize the selection.
  • append()
    Add a new point
  • move() 
    Change the position of the last point.
  • remove()
    Remove the last point.
  • end()
    Terminate the selection and call accept to validate the picked points.

The picker is active (isActive()), between begin() and end().In active state the rubberband is displayed, and the tracker is visible in case of trackerMode is ActiveOnly or AlwaysOn.

The cursor can be moved using the arrow keys. All selections can be aborted using the abort key.(QwtEventPattern::KeyPatternCode)

Warning:
In case of QWidget::NoFocus the focus policy of the observed widget is set to QWidget::WheelFocus and mouse tracking will be manipulated while the picker is active, or if  trackerMode() is AlwayOn.
代码分析:

1、构造函数:

/*!
  Constructor

  Creates an picker that is enabled, but without a state machine.
  rubberband and tracker are disabled.

  \param parent Parent widget, that will be observed
 */

QwtPicker::QwtPicker( QWidget *parent ):
    QObject( parent )
{
    init( parent, NoRubberBand, AlwaysOff );
}
注意:1)没有状态机。因此需要通过setStateMachine( QwtPickerMachine * sm)进行设置。

            2)rubberband and tracker are disabled.

2、设置状态机:

/*!
  Set a state machine and delete the previous one

  \param stateMachine State machine
  \sa stateMachine()
*/
void QwtPicker::setStateMachine( QwtPickerMachine *stateMachine )
{
    if ( d_data->stateMachine != stateMachine )
    {
        reset();

        delete d_data->stateMachine;
        d_data->stateMachine = stateMachine;

        if ( d_data->stateMachine )
            d_data->stateMachine->reset();
    }
}
说明:1)QwtPicker类和QwtPlotPicker类在实例化时,都没有初始化状态机,因此需要单独设置状态机。

            2)注意 setStateMachine( QwtPickerMachine * sm) 函数里的参数类型 QwtPickerMachine 是一个接口类,是所有其它状态机类型的抽象基类。这样我们就可以通过这个接口设置任意类型的状态机类型,包括我们自定义的状态机类型(只要它们是从QwtPickerMachine 派生而来)。 这个设计也充分印证了面向对象设计的一个原则:依赖倒置原则,即面向接口编程,而不是面向实现编程。

3、几个重要的函数接口: 

    virtual QRect pickRect() const;

    virtual void drawRubberBand( QPainter * ) const; // 绘制RubberBand,可以是横线,竖线,十字架,矩形,椭圆,多边形等多种形状
    virtual void drawTracker( QPainter * ) const; // 绘制显示鼠标点位置的(活动)标签(轨迹点文本)

    virtual QwtText trackerText( const QPoint &pos ) const; // 返回鼠标点的文本标签QwtText,通过重实现它可以实现不同样式的文本标签QwtText
    QPoint trackerPosition() const;
    virtual QRect trackerRect( const QFont & ) const;

    QPolygon selection() const; // 选择区域的多边形
4、QwtPicker类提供了丰富的属性设置接口,可以通过设置不同的属性得到漂亮满意的样式。此外,QwtPicker类还提供了几个重要的信号,为我们在拾取过程中捕获相关特征参数提供了方便。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值