📄 qwt_thermo.cpp
字号:
/* -*- 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 + -