詳解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;

 

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