From edcad1f34bdc9309f929237ef19ffac13dd333f6 Mon Sep 17 00:00:00 2001 From: feiyangqingyun Date: Wed, 23 Oct 2019 14:32:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=94=B5=E6=B1=A0=E7=94=B5?= =?UTF-8?q?=E9=87=8F=E6=8E=A7=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- battery/battery.cpp | 386 +++++++++++++++++++++++++++++++++++++++++ battery/battery.h | 154 ++++++++++++++++ battery/battery.pro | 23 +++ battery/frmbattery.cpp | 21 +++ battery/frmbattery.h | 26 +++ battery/frmbattery.ui | 56 ++++++ battery/main.cpp | 31 ++++ 8 files changed, 699 insertions(+), 1 deletion(-) create mode 100644 battery/battery.cpp create mode 100644 battery/battery.h create mode 100644 battery/battery.pro create mode 100644 battery/frmbattery.cpp create mode 100644 battery/frmbattery.h create mode 100644 battery/frmbattery.ui create mode 100644 battery/main.cpp diff --git a/README.md b/README.md index a12e7f9..f65922b 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,5 @@ | 17 | savelog | 日志重定向输出类 | | 18 | saveruntime | 运行时间记录类 | | 19 | colorwidget | 颜色拾取器 | -| 20 | maskwidget | 遮罩层窗体 | \ No newline at end of file +| 20 | maskwidget | 遮罩层窗体 | +| 21 | battery | 电池电量控件 | \ No newline at end of file diff --git a/battery/battery.cpp b/battery/battery.cpp new file mode 100644 index 0000000..6e86318 --- /dev/null +++ b/battery/battery.cpp @@ -0,0 +1,386 @@ +#pragma execution_character_set("utf-8") + +#include "battery.h" +#include "qpainter.h" +#include "qtimer.h" +#include "qdebug.h" + +Battery::Battery(QWidget *parent) : QWidget(parent) +{ + minValue = 0; + maxValue = 100; + value = 0; + alarmValue = 30; + step = 0.5; + + borderRadius = 8; + bgRadius = 5; + headRadius = 3; + + borderColorStart = QColor(100, 100, 100); + borderColorEnd = QColor(80, 80, 80); + alarmColorStart = QColor(250, 118, 113); + alarmColorEnd = QColor(204, 38, 38); + normalColorStart = QColor(50, 205, 51); + normalColorEnd = QColor(60, 179, 133); + + isForward = false; + currentValue = 0; + + timer = new QTimer(this); + timer->setInterval(10); + connect(timer, SIGNAL(timeout()), this, SLOT(updateValue())); +} + +Battery::~Battery() +{ + if (timer->isActive()) { + timer->stop(); + } +} + +void Battery::paintEvent(QPaintEvent *) +{ + //绘制准备工作,启用反锯齿 + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + //绘制边框 + drawBorder(&painter); + //绘制背景 + drawBg(&painter); + //绘制头部 + drawHead(&painter); +} + +void Battery::drawBorder(QPainter *painter) +{ + painter->save(); + + double headWidth = width() / 10; + double batteryWidth = width() - headWidth; + + //绘制电池边框 + QPointF topLeft(5, 5); + QPointF bottomRight(batteryWidth, height() - 5); + batteryRect = QRectF(topLeft, bottomRight); + + painter->setPen(QPen(borderColorStart, 5)); + painter->setBrush(Qt::NoBrush); + painter->drawRoundedRect(batteryRect, borderRadius, borderRadius); + + painter->restore(); +} + +void Battery::drawBg(QPainter *painter) +{ + painter->save(); + + QLinearGradient batteryGradient(QPointF(0, 0), QPointF(0, height())); + if (currentValue <= alarmValue) { + batteryGradient.setColorAt(0.0, alarmColorStart); + batteryGradient.setColorAt(1.0, alarmColorEnd); + } else { + batteryGradient.setColorAt(0.0, normalColorStart); + batteryGradient.setColorAt(1.0, normalColorEnd); + } + + int margin = qMin(width(), height()) / 20; + double unit = (batteryRect.width() - (margin * 2)) / 100; + double width = currentValue * unit; + QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin); + QPointF bottomRight(width + margin + 5, batteryRect.bottomRight().y() - margin); + QRectF rect(topLeft, bottomRight); + + painter->setPen(Qt::NoPen); + painter->setBrush(batteryGradient); + painter->drawRoundedRect(rect, bgRadius, bgRadius); + + painter->restore(); +} + +void Battery::drawHead(QPainter *painter) +{ + painter->save(); + + QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3); + QPointF headRectBottomRight(width(), height() - height() / 3); + QRectF headRect(headRectTopLeft, headRectBottomRight); + + QLinearGradient headRectGradient(headRect.topLeft(), headRect.bottomLeft()); + headRectGradient.setColorAt(0.0, borderColorStart); + headRectGradient.setColorAt(1.0, borderColorEnd); + + painter->setPen(Qt::NoPen); + painter->setBrush(headRectGradient); + painter->drawRoundedRect(headRect, headRadius, headRadius); + + painter->restore(); +} + +void Battery::updateValue() +{ + if (isForward) { + currentValue -= step; + + if (currentValue <= value) { + timer->stop(); + } + } else { + currentValue += step; + + if (currentValue >= value) { + timer->stop(); + } + } + + this->update(); +} + +double Battery::getMinValue() const +{ + return this->minValue; +} + +double Battery::getMaxValue() const +{ + return this->maxValue; +} + +double Battery::getValue() const +{ + return this->value; +} + +double Battery::getAlarmValue() const +{ + return this->alarmValue; +} + +double Battery::getStep() const +{ + return this->step; +} + +int Battery::getBorderRadius() const +{ + return this->borderRadius; +} + +int Battery::getBgRadius() const +{ + return this->bgRadius; +} + +int Battery::getHeadRadius() const +{ + return this->headRadius; +} + +QColor Battery::getBorderColorStart() const +{ + return this->borderColorStart; +} + +QColor Battery::getBorderColorEnd() const +{ + return this->borderColorEnd; +} + +QColor Battery::getAlarmColorStart() const +{ + return this->alarmColorStart; +} + +QColor Battery::getAlarmColorEnd() const +{ + return this->alarmColorEnd; +} + +QColor Battery::getNormalColorStart() const +{ + return this->normalColorStart; +} + +QColor Battery::getNormalColorEnd() const +{ + return this->normalColorEnd; +} + +QSize Battery::sizeHint() const +{ + return QSize(150, 80); +} + +QSize Battery::minimumSizeHint() const +{ + return QSize(30, 10); +} + +void Battery::setRange(double minValue, double maxValue) +{ + //如果最小值大于或者等于最大值则不设置 + if (minValue >= maxValue) { + return; + } + + this->minValue = minValue; + this->maxValue = maxValue; + + //如果目标值不在范围值内,则重新设置目标值 + //值小于最小值则取最小值,大于最大值则取最大值 + if (value < minValue) { + setValue(minValue); + } else if (value > maxValue) { + setValue(maxValue); + } + + this->update(); +} + +void Battery::setRange(int minValue, int maxValue) +{ + setRange((double)minValue, (double)maxValue); +} + +void Battery::setMinValue(double minValue) +{ + setRange(minValue, maxValue); +} + +void Battery::setMaxValue(double maxValue) +{ + setRange(minValue, maxValue); +} + +void Battery::setValue(double value) +{ + //值和当前值一致则无需处理 + if (value == this->value) { + return; + } + + //值小于最小值则取最小值,大于最大值则取最大值 + if (value < minValue) { + value = minValue; + } else if (value > maxValue) { + value = maxValue; + } + + if (value > currentValue) { + isForward = false; + } else if (value < currentValue) { + isForward = true; + } else { + return; + } + + this->value = value; + this->update(); + emit valueChanged(value); + timer->start(); +} + +void Battery::setValue(int value) +{ + setValue((double)value); +} + +void Battery::setAlarmValue(double alarmValue) +{ + if (this->alarmValue != alarmValue) { + this->alarmValue = alarmValue; + this->update(); + } +} + +void Battery::setAlarmValue(int alarmValue) +{ + setAlarmValue((double)alarmValue); +} + +void Battery::setStep(double step) +{ + if (this->step != step) { + this->step = step; + this->update(); + } +} + +void Battery::setStep(int step) +{ + setStep((double)step); +} + +void Battery::setBorderRadius(int borderRadius) +{ + if (this->borderRadius != borderRadius) { + this->borderRadius = borderRadius; + this->update(); + } +} + +void Battery::setBgRadius(int bgRadius) +{ + if (this->bgRadius != bgRadius) { + this->bgRadius = bgRadius; + this->update(); + } +} + +void Battery::setHeadRadius(int headRadius) +{ + if (this->headRadius != headRadius) { + this->headRadius = headRadius; + this->update(); + } +} + +void Battery::setBorderColorStart(const QColor &borderColorStart) +{ + if (this->borderColorStart != borderColorStart) { + this->borderColorStart = borderColorStart; + this->update(); + } +} + +void Battery::setBorderColorEnd(const QColor &borderColorEnd) +{ + if (this->borderColorEnd != borderColorEnd) { + this->borderColorEnd = borderColorEnd; + this->update(); + } +} + +void Battery::setAlarmColorStart(const QColor &alarmColorStart) +{ + if (this->alarmColorStart != alarmColorStart) { + this->alarmColorStart = alarmColorStart; + this->update(); + } +} + +void Battery::setAlarmColorEnd(const QColor &alarmColorEnd) +{ + if (this->alarmColorEnd != alarmColorEnd) { + this->alarmColorEnd = alarmColorEnd; + this->update(); + } +} + +void Battery::setNormalColorStart(const QColor &normalColorStart) +{ + if (this->normalColorStart != normalColorStart) { + this->normalColorStart = normalColorStart; + this->update(); + } +} + +void Battery::setNormalColorEnd(const QColor &normalColorEnd) +{ + if (this->normalColorEnd != normalColorEnd) { + this->normalColorEnd = normalColorEnd; + this->update(); + } +} + diff --git a/battery/battery.h b/battery/battery.h new file mode 100644 index 0000000..697bda5 --- /dev/null +++ b/battery/battery.h @@ -0,0 +1,154 @@ +#ifndef BATTERY_H +#define BATTERY_H + +/** + * 电池电量控件 作者:feiyangqingyun(QQ:517216493) 2016-10-23 + * 1:可设置电池电量,动态切换电池电量变化 + * 2:可设置电池电量警戒值 + * 3:可设置电池电量正常颜色和报警颜色 + * 4:可设置边框渐变颜色 + * 5:可设置电量变化时每次移动的步长 + * 6:可设置边框圆角角度/背景进度圆角角度/头部圆角角度 + */ + +#include + +#ifdef quc +#if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) +#include +#else +#include +#endif + +class QDESIGNER_WIDGET_EXPORT Battery : public QWidget +#else +class Battery : public QWidget +#endif + +{ + Q_OBJECT + Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue) + Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue) + Q_PROPERTY(double value READ getValue WRITE setValue) + Q_PROPERTY(double alarmValue READ getAlarmValue WRITE setAlarmValue) + + Q_PROPERTY(double step READ getStep WRITE setStep) + Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius) + Q_PROPERTY(int bgRadius READ getBgRadius WRITE setBgRadius) + Q_PROPERTY(int headRadius READ getHeadRadius WRITE setHeadRadius) + + Q_PROPERTY(QColor borderColorStart READ getBorderColorStart WRITE setBorderColorStart) + Q_PROPERTY(QColor borderColorEnd READ getBorderColorEnd WRITE setBorderColorEnd) + + Q_PROPERTY(QColor alarmColorStart READ getAlarmColorStart WRITE setAlarmColorStart) + Q_PROPERTY(QColor alarmColorEnd READ getAlarmColorEnd WRITE setAlarmColorEnd) + + Q_PROPERTY(QColor normalColorStart READ getNormalColorStart WRITE setNormalColorStart) + Q_PROPERTY(QColor normalColorEnd READ getNormalColorEnd WRITE setNormalColorEnd) + +public: + explicit Battery(QWidget *parent = 0); + ~Battery(); + +protected: + void paintEvent(QPaintEvent *); + void drawBorder(QPainter *painter); + void drawBg(QPainter *painter); + void drawHead(QPainter *painter); + +private slots: + void updateValue(); + +private: + double minValue; //最小值 + double maxValue; //最大值 + double value; //目标电量 + double alarmValue; //电池电量警戒值 + + double step; //每次移动的步长 + int borderRadius; //边框圆角角度 + int bgRadius; //背景进度圆角角度 + int headRadius; //头部圆角角度 + + QColor borderColorStart; //边框渐变开始颜色 + QColor borderColorEnd; //边框渐变结束颜色 + + QColor alarmColorStart; //电池低电量时的渐变开始颜色 + QColor alarmColorEnd; //电池低电量时的渐变结束颜色 + + QColor normalColorStart; //电池正常电量时的渐变开始颜色 + QColor normalColorEnd; //电池正常电量时的渐变结束颜色 + + bool isForward; //是否往前移 + double currentValue; //当前电量 + QRectF batteryRect; //电池主体区域 + QTimer *timer; //绘制定时器 + +public: + double getMinValue() const; + double getMaxValue() const; + double getValue() const; + double getAlarmValue() const; + + double getStep() const; + int getBorderRadius() const; + int getBgRadius() const; + int getHeadRadius() const; + + QColor getBorderColorStart() const; + QColor getBorderColorEnd() const; + + QColor getAlarmColorStart() const; + QColor getAlarmColorEnd() const; + + QColor getNormalColorStart() const; + QColor getNormalColorEnd() const; + + QSize sizeHint() const; + QSize minimumSizeHint() const; + +public Q_SLOTS: + //设置范围值 + void setRange(double minValue, double maxValue); + void setRange(int minValue, int maxValue); + + //设置最大最小值 + void setMinValue(double minValue); + void setMaxValue(double maxValue); + + //设置电池电量值 + void setValue(double value); + void setValue(int value); + + //设置电池电量警戒值 + void setAlarmValue(double alarmValue); + void setAlarmValue(int alarmValue); + + //设置步长 + void setStep(double step); + void setStep(int step); + + //设置边框圆角角度 + void setBorderRadius(int borderRadius); + //设置背景圆角角度 + void setBgRadius(int bgRadius); + //设置头部圆角角度 + void setHeadRadius(int headRadius); + + //设置边框渐变颜色 + void setBorderColorStart(const QColor &borderColorStart); + void setBorderColorEnd(const QColor &borderColorEnd); + + //设置电池电量报警时的渐变颜色 + void setAlarmColorStart(const QColor &alarmColorStart); + void setAlarmColorEnd(const QColor &alarmColorEnd); + + //设置电池电量正常时的渐变颜色 + void setNormalColorStart(const QColor &normalColorStart); + void setNormalColorEnd(const QColor &normalColorEnd); + +Q_SIGNALS: + void valueChanged(double value); +}; + +#endif // BATTERY_H diff --git a/battery/battery.pro b/battery/battery.pro new file mode 100644 index 0000000..236fb5f --- /dev/null +++ b/battery/battery.pro @@ -0,0 +1,23 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-02-08T09:46:02 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = battery +TEMPLATE = app +DESTDIR = $$PWD/../bin +CONFIG += warn_off + +SOURCES += main.cpp +SOURCES += frmbattery.cpp +SOURCES += battery.cpp + +HEADERS += frmbattery.h +HEADERS += battery.h + +FORMS += frmbattery.ui diff --git a/battery/frmbattery.cpp b/battery/frmbattery.cpp new file mode 100644 index 0000000..e6d157e --- /dev/null +++ b/battery/frmbattery.cpp @@ -0,0 +1,21 @@ +#pragma execution_character_set("utf-8") + +#include "frmbattery.h" +#include "ui_frmbattery.h" + +frmBattery::frmBattery(QWidget *parent) : QWidget(parent), ui(new Ui::frmBattery) +{ + ui->setupUi(this); + this->initForm(); +} + +frmBattery::~frmBattery() +{ + delete ui; +} + +void frmBattery::initForm() +{ + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->battery, SLOT(setValue(int))); + ui->horizontalSlider->setValue(30); +} diff --git a/battery/frmbattery.h b/battery/frmbattery.h new file mode 100644 index 0000000..4138c66 --- /dev/null +++ b/battery/frmbattery.h @@ -0,0 +1,26 @@ +#ifndef FRMBATTERY_H +#define FRMBATTERY_H + +#include + +namespace Ui +{ +class frmBattery; +} + +class frmBattery : public QWidget +{ + Q_OBJECT + +public: + explicit frmBattery(QWidget *parent = 0); + ~frmBattery(); + +private: + Ui::frmBattery *ui; + +private slots: + void initForm(); +}; + +#endif // FRMBATTERY_H diff --git a/battery/frmbattery.ui b/battery/frmbattery.ui new file mode 100644 index 0000000..59270b5 --- /dev/null +++ b/battery/frmbattery.ui @@ -0,0 +1,56 @@ + + + frmBattery + + + + 0 + 0 + 500 + 300 + + + + Form + + + + + 9 + 9 + 482 + 257 + + + + + + + 9 + 272 + 481 + 19 + + + + 100 + + + Qt::Horizontal + + + false + + + + + + Battery + QWidget +
battery.h
+ 1 +
+
+ + +
diff --git a/battery/main.cpp b/battery/main.cpp new file mode 100644 index 0000000..8f88677 --- /dev/null +++ b/battery/main.cpp @@ -0,0 +1,31 @@ +#pragma execution_character_set("utf-8") + +#include "frmbattery.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + a.setFont(QFont("Microsoft Yahei", 9)); + +#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); +#endif + + frmBattery w; + w.setWindowTitle("电池电量控件"); + w.show(); + + return a.exec(); +}