#include "mywidget.h"
#include <QStyleOption>
#include <QPainter>
#include <QTimer>
#include <QtDebug>
#include <QtMath>
MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
}
void MyWidget::setCurrentValue(int value)
{
currentValue = value;
update();
}
void MyWidget::paintEvent(QPaintEvent *event)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height);
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
painter.translate(width/2, height/2);
painter.scale(side/200.0, side/200.0);
// 表盘
drawArc(&painter);
drawScale(&painter);
drawScaleNum(&painter);
//根据指示器形状绘制指示器
if (pointerStyle == PointerStyle_Circle) {
drawPointerCircle(&painter);
} else if (pointerStyle == PointerStyle_Indicator) {
drawPointerIndicator(&painter);
} else if (pointerStyle == PointerStyle_IndicatorR) {
drawPointerIndicatorR(&painter);
} else if (pointerStyle == PointerStyle_Triangle) {
drawPointerTriangle(&painter);
}
//指针
drawRoundCircle(&painter);
drawCenterCircle(&painter);
//当前值
drawValue(&painter);
}
void MyWidget::drawArc(QPainter *painter)
{
painter->save();
QPen pen;
pen.setColor(QColor(137, 207, 240));
pen.setWidthF(2);
painter->setPen(pen);
painter->setBrush(Qt::NoBrush);
double angleAll = 360 - startAngle - endAngle;
double angleCur = angleAll * ((currentValue - minValue) / (maxValue - minValue));
double angleOther = angleAll - angleCur;
// outer arc
int radius = 98;
QRectF rect = QRectF(-radius, -radius, radius * 2, radius * 2);
painter->drawArc(rect, (270 - startAngle - angleCur)*16, angleCur*16);
painter->drawArc(rect, (270 - startAngle - angleCur - angleOther)*16, angleOther*16);
// inner arc
radius = 90;
rect = QRectF(-radius, -radius, radius * 2, radius * 2);
painter->drawArc(rect, (270 - startAngle - angleCur) * 16, angleCur * 16);
painter->drawArc(rect, (270 - startAngle - angleCur - angleOther) * 16, angleOther * 16);
painter->restore();
}
void MyWidget::drawScale(QPainter *painter)
{
int radius = 97;
painter->save();
painter->rotate(startAngle);
int steps = (scaleMajor + scaleMinor);
double angleStep = (360 - startAngle - endAngle) / steps;
QPen pen;
pen.setColor(QColor(137, 207, 240));
pen.setCapStyle(Qt::RoundCap);
for (int i = 0; i <= steps; i++) {
if (i % scaleMajor == 0) {
pen.setWidthF(1.5);
painter->setPen(pen);
painter->drawLine(0, radius - 12, 0, radius);
} else {
pen.setWidthF(1.0);
painter->setPen(pen);
painter->drawLine(0, radius - 6, 0, radius);
}
painter->rotate(angleStep);
}
painter->restore();
}
void MyWidget::drawScaleNum(QPainter *painter)
{
int radius = 75;
painter->save();
QFont font;
font.setFamily("微软雅黑");
painter->setFont(font);
painter->setPen(QColor(137, 207, 240));
double startRad = (360 - startAngle - 90) * (M_PI / 180);
double deltaRad = (360 - startAngle - endAngle) * (M_PI / 180) / scaleMajor;
for (int i = 0; i <= scaleMajor; i++) {
double sina = qSin(startRad - i * deltaRad);
double cosa = qCos(startRad - i * deltaRad);
double value = 1.0 * i * ((maxValue - minValue) / scaleMajor) + minValue;
QString strValue = QString("%1").arg((double)value, 0, 'f', 0);
double textWidth = fontMetrics().width(strValue);
double textHeight = fontMetrics().height();
int x = radius * cosa - textWidth / 2;
int y = -radius * sina + textHeight / 4;
painter->drawText(x, y, strValue);
}
painter->restore();
}
void MyWidget::drawPointerCircle(QPainter *painter)
{
int radius = 8;
int offset = 30;
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
painter->rotate(startAngle);
double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
painter->rotate(degRotate);
painter->drawEllipse(-radius, radius + offset, radius * 2, radius * 2);
painter->restore();
}
void MyWidget::drawPointerIndicator(QPainter *painter)
{
int radius = 75;
painter->save();
painter->setOpacity(0.8);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
QPolygon pts;
pts.setPoints(3, -5, 0, 5, 0, 0, radius);
painter->rotate(startAngle);
double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
painter->rotate(degRotate);
painter->drawConvexPolygon(pts);
painter->restore();
}
void MyWidget::drawPointerIndicatorR(QPainter *painter)
{
int radius = 75;
painter->save();
QPen pen;
pen.setWidthF(1);
pen.setColor(Qt::red);
painter->setPen(pen);
painter->setBrush(Qt::NoBrush);
QPolygon pts;
pts.setPoints(3, -5, 0, 5, 0, 0, radius);
painter->rotate(startAngle);
double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
painter->rotate(degRotate);
painter->drawConvexPolygon(pts);
pen.setCapStyle(Qt::RoundCap);
pen.setWidthF(4);
painter->setPen(pen);
painter->drawLine(0, 0, 0, radius);
painter->restore();
}
void MyWidget::drawPointerTriangle(QPainter *painter)
{
int radius = 10;
int offset = 55;
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
QPolygon pts;
pts.setPoints(3, -5, 0 + offset, 5, 0 + offset, 0, radius + offset);
painter->rotate(startAngle);
double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (currentValue - minValue);
painter->rotate(degRotate);
painter->drawConvexPolygon(pts);
painter->restore();
}
void MyWidget::drawRoundCircle(QPainter *painter)
{
int radius = 12;
painter->save();
painter->setOpacity(0.5);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
painter->restore();
}
void MyWidget::drawCenterCircle(QPainter *painter)
{
int radius = 8;
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::red);
painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
painter->restore();
}
void MyWidget::drawValue(QPainter *painter)
{
int radius = 100;
painter->save();
painter->setPen(QColor(137, 207, 240));
QFont font;
font.setFamily("微软雅黑");
font.setPixelSize(30);
painter->setFont(font);
QRectF textRect(-radius, radius / 2, radius * 2, radius / 3);
QString strValue = QString("%1").arg((double)currentValue, 0, 'f', 0);
painter->drawText(textRect, Qt::AlignCenter, strValue);
painter->restore();
}
QSize MyWidget::sizeHint() const
{
return QSize(300, 300);
}