详解QwtScaleDraw

继承关系图:

官方文档

A class for drawing scales.

QwtScaleDraw can be used to draw linear or logarithmic scales. A scale has a position, an alignment and a length, which can be specified . The labels can be rotated and aligned to the ticks using setLabelRotation() and setLabelAlignment().

After a scale division has been specified as a QwtScaleDiv object using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s), the scale can be drawn with the QwtAbstractScaleDraw::draw() member.

中文翻译

一个绘制刻度尺的类。

QwtScaleDraw可以被用来绘制线性或者对数的刻度。刻度尺有位置(QwtPlot::Axis),对齐方式(两种,label对齐和title对齐)和长度,这三个属性都可以被特例化(可以被重载)。使用setLabelRotation()可以旋转labels,使用setLabelAlignment()可以设置对齐方式。

使用QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s)可以对刻度尺进行划分,刻度尺划分的类是QwtScaleDiv

使用QwtAbstractScaleDraw::draw() 可以对刻度尺进行重绘。

具体解释:

从使用的角度看,我们一般只了解set的函数或者virtual函数就可以了,如果想要了解的更详细些,可以去看文件qwt_scale_draw.h和qwt_scale_draw.cpp。所以针对使用,我们研究下面几个就可以了。

class QWT_EXPORT QwtScaleDraw: public QwtAbstractScaleDraw
{
public:
    .......
    enum Alignment 
    { 
        //! The scale is below
        BottomScale, 

        //! The scale is above
        TopScale, 

        //! The scale is left
        LeftScale, 

        //! The scale is right
        RightScale 
    };

    QwtScaleDraw();
    virtual ~QwtScaleDraw();

    
    virtual double extent( const QFont & ) const;

    void move( double x, double y );
    void move( const QPointF & );
    void setLength( double length );
   
    void setAlignment( Alignment );

    void setLabelAlignment( Qt::Alignment );
    
    void setLabelRotation( double rotation );
 

    .......

protected:
    .......

    virtual void drawTick( QPainter *, double val, double len ) const;
    virtual void drawBackbone( QPainter * ) const;
    virtual void drawLabel( QPainter *, double val ) const;

.......
};

先解释下setAlignment,在barchart例子中增加一行代码如下

在void BarChart::setOrientation( int orientation )

{
    ......
    scaleDraw2->setAlignment(QwtScaleDraw::TopScale);
}

 效果图为:

从效果图中可以看出setAlignment是对whatever对齐,也就是说对title对齐。目前显示的隐藏掉 了一部分。

在barchart例子中并没有设置setAlignment这个属性,只是会根据QwtPlot中的

enum Axis
    {
        //! Y axis left of the canvas
        yLeft,

        //! Y axis right of the canvas
        yRight,

        //! X axis below the canvas
        xBottom,

        //! X axis above the canvas
        xTop,

        //! Number of axes
        axisCnt
    };

做默认设置。

在barchart例子中BarChart的构造中可以看到如下设置:

setAxisTitle( QwtPlot::yLeft, "Whatever" );
setAxisTitle( QwtPlot::xBottom, "Whatever" );

如果设置Axis为yLeft,就会默认设置setAlignment(QwtScaleDraw::LeftScale);

如果设置Axis为xBottom,就会默认设置setAlignment(QwtScaleDraw::BottomScale);

setLabelAlignment:

增加一行:

void BarChart::setOrientation( int orientation )
{
    scaleDraw1->setLabelAlignment(Qt::AlignLeft);
}

效果前后对比:

设置前:1的位置基本在第二个的正中间

设置后:1的位置基本的第二个的左侧了

换成文字显示会更明显:

setLabelRotation:

void BarChart::setOrientation( int orientation )
{
    .....
    scaleDraw1->setLabelRotation( 20.0 );
    .....
}

效果图:

可以看出字体斜了,说明旋转了一定的角度。

QwtAbstractScaleDraw::draw()

了解QwtAbstractScaleDraw::draw()不妨先了解下QwtScaleDraw的基类QwtAbstractScaleDraw.可以查看我的关于QwtAbstractScaleDraw的文章。

QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s)

可以看QwtScaleDiv的文章

double QwtScaleDraw::extent( const QFont &font ) const:

double QwtScaleDraw::extent( const QFont &font ) const
{
    double d = 0;
    
    // 有控件labels吗
    if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
    {
        if ( orientation() == Qt::Vertical )
            d = maxLabelWidth( font );
        else
            d = maxLabelHeight( font );

        if ( d > 0 )
            //加上布局的空间
            d += spacing();
    }

    //有刻度吗?
    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
    {
        //刻度分为min,major,所以需要最长的刻度
        d += maxTickLength();
    }

    //有刻度基线吗(下面有解释)
    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
    {
        const double pw = qMax( 1, penWidth() );  // pen width can be zero
        d += pw;
    }
    
    //最后算出三个控件加起来的界面允许的最大值
    d = qMax( d, minimumExtent() );
    return d;
}

backbone的含义:

箭头指向的从0到8的那条最长的竖线为基线

在barchart的例子中

scaleDraw2->enableComponent( QwtScaleDraw::Backbone, true );可以设置为false测试下,会发现没有基线了。效果图为:

所以whatever  +  0-8的任意一个数的宽度(垂直)或高度(水平) +  基线  + space就是界面允许的最大的范围值。

这三行为重绘刻度,重绘基线,重绘labels。

virtual void drawTick( QPainter *, double val, double len ) const;
virtual void drawBackbone( QPainter * ) const;
virtual void drawLabel( QPainter *, double val ) const;

 

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