前言
基于QWidget实现的仪表盘控件。效果如图,代码自取,请放心食用(建议使用Qt中提升控件方法使用)。
源码
fr_dash_board.h
#ifndef FR_DASH_BOARD_H
#define FR_DASH_BOARD_H
#include <qwidget.h>
class FrDashBoard : public QWidget {
Q_OBJECT
public:
explicit FrDashBoard(QWidget *parent = nullptr);
void set_range(const double min, const double max);
void set_min_range(const double min);
void set_max_range(const double max);
void set_unit(const QString& unit);
void set_text(const QString& text);
public slots:
void set_value(const double value);
protected:
void paintEvent(QPaintEvent *event);
private:
void draw_dash_board(QPainter& painter);
void draw_hand(QPainter& painter);
void draw_value(QPainter& painter);
void draw_text(QPainter& painter);
private:
double _value;
double _min;
double _max;
QString _unit;
QString _text;
};
#endif // FR_DASH_BOARD_H
fr_dash_board.cpp
#include "fr_dash_board.h"
#include <qevent.h>
#include <qpainter.h>
#include <qpainterpath.h>
#include <qrect.h>
#include <qmath.h>
#include <qstring.h>
FrDashBoard::FrDashBoard(QWidget *parent) :
QWidget(parent),
_value(0),
_min(0.0),
_max(2.0) {
}
void FrDashBoard::set_range(const double min, const double max) {
_min = min;
_max = max;
update();
}
void FrDashBoard::set_min_range(const double min) {
_min = min;
update();
}
void FrDashBoard::set_max_range(const double max) {
_max = max;
update();
}
void FrDashBoard::set_unit(const QString& unit) {
_unit = unit;
update();
}
void FrDashBoard::set_text(const QString& text) {
_text = text;
update();
}
void FrDashBoard::set_value(const double value) {
if (value < _min) {
_value = _min;
} else if (value > _max) {
_value = _max;
} else {
_value = value;
}
update();
}
void FrDashBoard::paintEvent(QPaintEvent *event) {
QWidget::paintEvent(event);
int side = qMin(int(height() / 8.5 * 10.0), width());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
painter.translate(0, 15);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::NoBrush);
draw_dash_board(painter);
draw_hand(painter);
draw_value(painter);
draw_text(painter);
}
void FrDashBoard::draw_dash_board(QPainter &painter) {
painter.save();
painter.setPen(QPen(QColor(96, 96, 96, 196), 12, Qt::SolidLine));
QRectF rectangle(-67, -67, 134, 134);
int startAngle = -40 * 16;
int spanAngle = 260 * 16;
painter.drawArc(rectangle, startAngle, spanAngle);
painter.save();
painter.setPen(QPen(QColor(26, 196, 196, 225), 0.75, Qt::SolidLine));
painter.rotate(-220);
for (int i = 0; i < 11; ++i) {
painter.drawLine(76, 0, 86, 0);
painter.rotate(26.0);
}
painter.restore();
painter.save();
painter.setPen(QPen(QColor(26, 196, 196, 225), 0.5, Qt::SolidLine));
painter.rotate(-220);
for (int i = 0; i < 50; ++i) {
painter.drawLine(76, 0, 82, 0);
painter.rotate(5.2);
}
painter.restore();
double range = _max - _min;
double step = range / 10.0;
for (int i = 0; i < 11; ++i) {
painter.save();
painter.setPen(QColor(26, 196, 196, 225));
painter.setFont(QFont("Times", 10));
painter.rotate(-220.0);
painter.rotate(26.0 * i);
painter.translate(95, 0);
painter.rotate(90.0);
painter.drawText(QRect(-19, -7, 38, 14), Qt::AlignCenter, QString::number(_min + i * step));
painter.restore();
}
painter.restore();
}
void FrDashBoard::draw_hand(QPainter &painter) {
static const QPoint hand[] = {
QPoint(-5, 0),
QPoint(0, -75),
QPoint(5, 0),
QPoint(0, 7)
};
painter.save();
painter.rotate(-130.0);
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(26, 196, 196));
painter.rotate(260.0 / (_max - _min) * _value);
painter.drawConvexPolygon(hand, 4);
painter.restore();
}
void FrDashBoard::draw_value(QPainter &painter) {
painter.save();
painter.setPen(QColor(96, 96, 96, 245));
painter.setFont(QFont("Times", 18));
QString unit;
if (!_unit.isEmpty()) {
unit = QString::number(_value) + " " + _unit;
} else {
unit = QString::number(_value);
}
painter.drawText(QRect(-100, 30, 200, 20), Qt::AlignCenter, unit);
painter.restore();
}
void FrDashBoard::draw_text(QPainter &painter) {
painter.save();
painter.setPen(QColor(96, 96, 96, 245));
painter.setFont(QFont("Times", 10));
painter.drawText(QRect(-100, 50, 200, 20), Qt::AlignCenter, _text);
painter.restore();
}