⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_thermo.cpp

📁 QWT5.01用于Qt开发的二维图形库程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

#include <qpainter.h>
#include <qevent.h>
#include <qstyle.h>
#include <qpixmap.h>
#include <qdrawutil.h>
#include "qwt_math.h"
#include "qwt_scale_engine.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_map.h"
#include "qwt_paint_buffer.h"
#include "qwt_thermo.h"

class QwtThermo::PrivateData
{
public:
    PrivateData():
        fillBrush(Qt::black),
        alarmBrush(Qt::white),
        orientation(Qt::Vertical),
        scalePos(QwtThermo::LeftScale),
        borderWidth(2),
        scaleDist(3),
        thermoWidth(10),
        minValue(0.0),
        maxValue(1.0),
        value(0.0),
        alarmLevel(0.0),
        alarmEnabled(false)
    {
        map.setScaleInterval(minValue, maxValue);
    }

    QwtScaleMap map;
    QRect thermoRect;
    QBrush fillBrush;
    QBrush alarmBrush;

    Qt::Orientation orientation;
    ScalePos scalePos;
    int borderWidth;
    int scaleDist;
    int thermoWidth;

    double minValue;
    double maxValue;
    double value;
    double alarmLevel;
    bool alarmEnabled;
};

/*! 
  Constructor
  \param parent Parent widget
*/
QwtThermo::QwtThermo(QWidget *parent): 
    QWidget(parent)
{
    initThermo();
}

#if QT_VERSION < 0x040000
/*! 
  Constructor
  \param parent Parent widget
  \param name Object name
*/
QwtThermo::QwtThermo(QWidget *parent, const char *name): 
    QWidget(parent, name)
{
    initThermo();
}
#endif

void QwtThermo::initThermo()
{
#if QT_VERSION < 0x040000
    setWFlags(Qt::WNoAutoErase);
#endif
    d_data = new PrivateData;
    setRange(d_data->minValue, d_data->maxValue, false);

    QSizePolicy policy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
    if (d_data->orientation == Qt::Vertical) 
        policy.transpose();

    setSizePolicy(policy);
    
#if QT_VERSION >= 0x040000
    setAttribute(Qt::WA_WState_OwnSizePolicy, false);
#else
    clearWState( WState_OwnSizePolicy );
#endif
}

//! Destructor
QwtThermo::~QwtThermo()
{
    delete d_data;
}

//! Set the maximum value.
void QwtThermo::setMaxValue(double v) 
{ 
    setRange(d_data->minValue, v); 
}

//! Return the maximum value.
double QwtThermo::maxValue() const 
{ 
    return d_data->maxValue; 
}

//! Set the minimum value.
void QwtThermo::setMinValue(double v) 
{ 
    setRange(v, d_data->maxValue); 
}

//! Return the minimum value.
double QwtThermo::minValue() const 
{ 
    return d_data->minValue; 
}

//! Set the current value.
void QwtThermo::setValue(double v)
{
    if (d_data->value != v)
    {
        d_data->value = v;
        update();
    }
}

//! Return the value.
double QwtThermo::value() const 
{ 
    return d_data->value; 
}

void QwtThermo::setScaleDraw(QwtScaleDraw *scaleDraw)
{
    setAbstractScaleDraw(scaleDraw);
}

const QwtScaleDraw *QwtThermo::scaleDraw() const
{
    return (QwtScaleDraw *)abstractScaleDraw();
}

QwtScaleDraw *QwtThermo::scaleDraw() 
{
    return (QwtScaleDraw *)abstractScaleDraw();
}

//! Qt paint event.
void QwtThermo::paintEvent(QPaintEvent *e)
{
    // Use double-buffering
    const QRect &ur = e->rect();
    if ( ur.isValid() )
    {
#if QT_VERSION < 0x040000
        QwtPaintBuffer paintBuffer(this, ur);
        draw(paintBuffer.painter(), ur);
#else
        QPainter painter(this);
        draw(&painter, ur);
#endif
    }
}

//! Draw the whole QwtThermo.
void QwtThermo::draw(QPainter *p, const QRect& ur)
{
    if ( !d_data->thermoRect.contains(ur) )
    {
        if (d_data->scalePos != NoScale)
        {
#if QT_VERSION < 0x040000
            scaleDraw()->draw(p, colorGroup());
#else
            scaleDraw()->draw(p, palette());
#endif
        }

        qDrawShadePanel(p,
            d_data->thermoRect.x() - d_data->borderWidth,
            d_data->thermoRect.y() - d_data->borderWidth,
            d_data->thermoRect.width() + 2*d_data->borderWidth,
            d_data->thermoRect.height() + 2*d_data->borderWidth,
#if QT_VERSION < 0x040000
            colorGroup(), 
#else
            palette(), 
#endif
            true, d_data->borderWidth,0);
    }
    drawThermo(p);
}

//! Qt resize event handler
void QwtThermo::resizeEvent(QResizeEvent *)
{
    layoutThermo( false );
}

/*!
  Recalculate the QwtThermo geometry and layout based on
  the QwtThermo::rect() and the fonts.
  \param update_geometry notify the layout system and call update
         to redraw the scale
*/
void QwtThermo::layoutThermo( bool update_geometry )
{
    QRect r = rect();
    int mbd = 0;
    if ( d_data->scalePos != NoScale )
    {
        int d1, d2;
        scaleDraw()->getBorderDistHint(font(), d1, d2);
        mbd = qwtMax(d1, d2);
    }

    if ( d_data->orientation == Qt::Horizontal )
    {
        switch ( d_data->scalePos )
        {
            case TopScale:
            {
                d_data->thermoRect.setRect(
                    r.x() + mbd + d_data->borderWidth,
                    r.y() + r.height()
                    - d_data->thermoWidth - 2*d_data->borderWidth,
                    r.width() - 2*(d_data->borderWidth + mbd),
                    d_data->thermoWidth);
                scaleDraw()->setAlignment(QwtScaleDraw::TopScale);
                scaleDraw()->move( d_data->thermoRect.x(),
                    d_data->thermoRect.y() - d_data->borderWidth 
                        - d_data->scaleDist);
                scaleDraw()->setLength(d_data->thermoRect.width());
                break;
            }

            case BottomScale:
            case NoScale: // like Bottom but without scale
            default:   // inconsistent orientation and scale position
                       // Mapping between values and pixels requires
                       // initialization of the scale geometry
            {
                d_data->thermoRect.setRect(
                    r.x() + mbd + d_data->borderWidth,
                    r.y() + d_data->borderWidth,
                    r.width() - 2*(d_data->borderWidth + mbd),
                    d_data->thermoWidth);
                scaleDraw()->setAlignment(QwtScaleDraw::BottomScale);
                scaleDraw()->move(
                    d_data->thermoRect.x(),
                    d_data->thermoRect.y() + d_data->thermoRect.height()
                        + d_data->borderWidth + d_data->scaleDist );
                scaleDraw()->setLength(d_data->thermoRect.width());
                break;
            }
        }
        d_data->map.setPaintInterval(d_data->thermoRect.x(),
            d_data->thermoRect.x() + d_data->thermoRect.width() - 1);
    }
    else // Qt::Vertical
    {
        switch ( d_data->scalePos )
        {
            case RightScale:
            {
                d_data->thermoRect.setRect(
                    r.x() + d_data->borderWidth,
                    r.y() + mbd + d_data->borderWidth,
                    d_data->thermoWidth,
                    r.height() - 2*(d_data->borderWidth + mbd));
                scaleDraw()->setAlignment(QwtScaleDraw::RightScale);
                scaleDraw()->move(
                    d_data->thermoRect.x() + d_data->thermoRect.width()
                        + d_data->borderWidth + d_data->scaleDist,
                    d_data->thermoRect.y());
                scaleDraw()->setLength(d_data->thermoRect.height());
                break;
            }

            case LeftScale:
            case NoScale: // like Left but without scale
            default:   // inconsistent orientation and scale position
                       // Mapping between values and pixels requires
                       // initialization of the scale geometry
            {
                d_data->thermoRect.setRect(
                    r.x() + r.width() - 2*d_data->borderWidth - d_data->thermoWidth,
                    r.y() + mbd + d_data->borderWidth,
                    d_data->thermoWidth,
                    r.height() - 2*(d_data->borderWidth + mbd));
                scaleDraw()->setAlignment(QwtScaleDraw::LeftScale);
                scaleDraw()->move(
                    d_data->thermoRect.x() - d_data->scaleDist 
                        - d_data->borderWidth,
                    d_data->thermoRect.y() );
                scaleDraw()->setLength(d_data->thermoRect.height());
                break;
            }
        }
        d_data->map.setPaintInterval(
            d_data->thermoRect.y() + d_data->thermoRect.height() - 1,
            d_data->thermoRect.y());
    }
    if ( update_geometry )
    {
        updateGeometry();
        update();
    }
}

/*!
  \brief Set the thermometer orientation and the scale position.

  The scale position NoScale disables the scale.
  \param o orientation. Possible values are Qt::Horizontal and Qt::Vertical.
         The default value is Qt::Vertical.
  \param s Position of the scale.
         The default value is NoScale.

  A valid combination of scale position and orientation is enforced:
  - a horizontal thermometer can have the scale positions TopScale, 
    BottomScale or NoScale;
  - a vertical thermometer can have the scale positions LeftScale, 
    RightScale or NoScale;
  - an invalid scale position will default to NoScale.

  \sa QwtThermo::setScalePosition()
*/
void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
{
    if ( o == d_data->orientation && s == d_data->scalePos )
        return;

    switch(o)
    {
        case Qt::Horizontal:
        {
            if ((s == NoScale) || (s == BottomScale) || (s == TopScale))
                d_data->scalePos = s;
            else
                d_data->scalePos = NoScale;
            break;
        }
        case Qt::Vertical:
        {
            if ((s == NoScale) || (s == LeftScale) || (s == RightScale))
                d_data->scalePos = s;
            else
                d_data->scalePos = NoScale;
            break;
        }
    }

    if ( o != d_data->orientation )
    {
#if QT_VERSION >= 0x040000
        if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
#else
        if ( !testWState( WState_OwnSizePolicy ) )
#endif
        {
            QSizePolicy sp = sizePolicy();
            sp.transpose();
            setSizePolicy(sp);

#if QT_VERSION >= 0x040000
            setAttribute(Qt::WA_WState_OwnSizePolicy, false);
#else
            clearWState( WState_OwnSizePolicy );
#endif
        }
    }

    d_data->orientation = o;
    layoutThermo();
}

/*!
  \brief Change the scale position (and thermometer orientation).

  \param s Position of the scale.
  
  A valid combination of scale position and orientation is enforced:
  - if the new scale position is LeftScale or RightScale, the 
    scale orientation will become Qt::Vertical;
  - if the new scale position is BottomScale or TopScale, the scale 
    orientation will become Qt::Horizontal;
  - if the new scale position is NoScale, the scale orientation will not change.

  \sa QwtThermo::setOrientation()
*/
void QwtThermo::setScalePosition(ScalePos s)
{
    if ((s == BottomScale) || (s == TopScale))
        setOrientation(Qt::Horizontal, s);
    else if ((s == LeftScale) || (s == RightScale))
        setOrientation(Qt::Vertical, s);
    else
        setOrientation(d_data->orientation, NoScale);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -