Skip to content

Commit

Permalink
Battery quick;
Browse files Browse the repository at this point in the history
  • Loading branch information
RealChuan committed Jan 27, 2024
1 parent 07d76e2 commit e2d8bc9
Show file tree
Hide file tree
Showing 14 changed files with 302 additions and 85 deletions.
40 changes: 22 additions & 18 deletions Battery/batterywidget.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#include "batterywidget.h"

#include <QPainter>
#include <QPropertyAnimation>
#include <QTextItem>
#include <QWheelEvent>
#include <QtMath>
#include <QtWidgets>

struct BatteryWidget::BatteryWidgetPrivate
class BatteryWidget::BatteryWidgetPrivate
{
public:
BatteryWidgetPrivate(BatteryWidget *q)
: q_ptr(q)
{}

BatteryWidget *q_ptr;

QColor borderColor = QColor(80, 80, 80);
QColor powerColor = QColor(65, 205, 82);
QColor alarmColor = QColor(250, 118, 113);
Expand All @@ -18,7 +21,7 @@ struct BatteryWidget::BatteryWidgetPrivate

BatteryWidget::BatteryWidget(QWidget *parent)
: QWidget(parent)
, d_ptr(new BatteryWidgetPrivate)
, d_ptr(new BatteryWidgetPrivate(this))
{
d_ptr->animation = new QPropertyAnimation(this, "value", this);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
Expand Down Expand Up @@ -73,14 +76,15 @@ auto BatteryWidget::minimumSizeHint() const -> QSize
void BatteryWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);

QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
double linew = 2 * painter.pen().widthF() / painter.transform().m11();
auto linew = 2 * painter.pen().widthF() / painter.transform().m11();

qreal headWidth = width() / 11;
qreal batteryWidth = width() - headWidth;
QRectF batteryRect = QRectF(QPointF(5, 5), QPointF(batteryWidth, height() - 5));
auto batteryRect = QRectF(QPointF(5, 5), QPointF(batteryWidth, height() - 5));

// 边框
drawBorder(&painter, batteryRect, linew);
Expand Down Expand Up @@ -127,33 +131,33 @@ void BatteryWidget::setValue(int value)
update();
}

void BatteryWidget::drawBorder(QPainter *painter, const QRectF &batteryRect, const double linew)
void BatteryWidget::drawBorder(QPainter *painter, const QRectF &batteryRect, const qreal linew)
{
painter->setPen(QPen(d_ptr->borderColor, linew));
painter->setBrush(Qt::NoBrush);
double borderRadius = batteryRect.height() / 30;
qreal borderRadius = batteryRect.height() / 30;
painter->drawRoundedRect(batteryRect, borderRadius, borderRadius);
}

void BatteryWidget::drawPower(QPainter *painter, const QRectF &batteryRect, const double linew)
void BatteryWidget::drawPower(QPainter *painter, const QRectF &batteryRect, const qreal linew)
{
QColor powerColoer = d_ptr->value > d_ptr->alarmValue ? d_ptr->powerColor : d_ptr->alarmColor;
double margin = qMin(width(), height()) / 50.0;
auto powerColoer = d_ptr->value > d_ptr->alarmValue ? d_ptr->powerColor : d_ptr->alarmColor;
qreal margin = qMin(width(), height()) / 50.0;
margin = qMax(margin, linew);
qreal unit = (batteryRect.width() - (margin * 2)) / 100;
QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin);
QPointF bottomRight(d_ptr->value * unit + margin + 5, batteryRect.bottomRight().y() - margin);
QRectF rect(topLeft, bottomRight);
double bgRadius = rect.height() / 30;
qreal bgRadius = rect.height() / 30;
painter->setPen(Qt::NoPen);
painter->setBrush(powerColoer);
painter->drawRoundedRect(rect, bgRadius, bgRadius);
}

void BatteryWidget::drawValue(QPainter *painter, const QRectF &batteryRect)
{
QColor fontColoer = d_ptr->value > d_ptr->alarmValue ? QColor(64, 65, 66) : d_ptr->alarmColor;
QString text = QString("%1%").arg(d_ptr->value);
auto fontColoer = d_ptr->value > d_ptr->alarmValue ? QColor(64, 65, 66) : d_ptr->alarmColor;
auto text = QString("%1%").arg(d_ptr->value);
QFont font("Microsoft YaHei", batteryRect.width() / 5);
font.setLetterSpacing(QFont::AbsoluteSpacing, batteryRect.width() / 25);
painter->setFont(font);
Expand All @@ -167,7 +171,7 @@ void BatteryWidget::drawHeader(QPainter *painter, const QRectF &batteryRect)
QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3);
QPointF headRectBottomRight(width(), height() - height() / 3);
QRectF headRect(headRectTopLeft, headRectBottomRight);
double headRadius = headRect.height() / 30;
qreal headRadius = headRect.height() / 30;
painter->setPen(Qt::NoPen);
painter->setBrush(d_ptr->borderColor);
painter->drawRoundedRect(headRect, headRadius, headRadius);
Expand Down
14 changes: 7 additions & 7 deletions Battery/batterywidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ class BatteryWidget : public QWidget
explicit BatteryWidget(QWidget *parent = nullptr);
~BatteryWidget() override;

[[nodiscard]] [[nodiscard]] auto sizeHint() const -> QSize override;
[[nodiscard]] [[nodiscard]] auto minimumSizeHint() const -> QSize override;
[[nodiscard]] auto sizeHint() const -> QSize override;
[[nodiscard]] auto minimumSizeHint() const -> QSize override;

void setBorderColor(const QColor &color);
[[nodiscard]] [[nodiscard]] auto borderColor() const -> QColor;
[[nodiscard]] auto borderColor() const -> QColor;

void setPowerColor(const QColor &color);
[[nodiscard]] [[nodiscard]] auto powerColor() const -> QColor;
[[nodiscard]] auto powerColor() const -> QColor;

void setAlarmColor(const QColor &color);
[[nodiscard]] [[nodiscard]] auto alarmColor() const -> QColor;
[[nodiscard]] auto alarmColor() const -> QColor;

void setValue(int value);
[[nodiscard]] [[nodiscard]] auto value() const -> int;
[[nodiscard]] auto value() const -> int;

signals:
void valueChanged(int value);
Expand All @@ -44,7 +44,7 @@ private slots:
void drawValue(QPainter *painter, const QRectF &batteryRect);
void drawHeader(QPainter *painter, const QRectF &batteryRect);

struct BatteryWidgetPrivate;
class BatteryWidgetPrivate;
QScopedPointer<BatteryWidgetPrivate> d_ptr;
};

Expand Down
8 changes: 4 additions & 4 deletions Battery/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
BatteryWidget *battery = new BatteryWidget(this);
QSlider *slider = new QSlider(this);
auto *battery = new BatteryWidget(this);
auto *slider = new QSlider(this);
slider->setRange(0, 100);
connect(slider, &QSlider::valueChanged, battery, &BatteryWidget::valueChanged);

QWidget *widget = new QWidget(this);
QHBoxLayout *layout = new QHBoxLayout(widget);
auto *widget = new QWidget(this);
auto *layout = new QHBoxLayout(widget);
layout->addWidget(battery);
layout->addWidget(slider);
setCentralWidget(widget);
Expand Down
53 changes: 53 additions & 0 deletions BatteryQuick/Battery.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import QtQuick

Rectangle {
id: root

width: 200
height: 100

property color borderColor: "#505008"
property color powerColor: "#41cd52"
property color alarmColor: "#fa7671"
property int alarmValue: 20
property int value: 0

Rectangle {
id: batteryRect

x: 10
y: 10
width: root.width - x * 3
height: root.height - y * 2
border.color: root.borderColor
border.width: 2
radius: 5

Rectangle {
x: batteryRect.border.width * 2
y: batteryRect.border.width * 2
width: (batteryRect.width - x * 2) * (value / 100)
height: batteryRect.height - y * 2
color: value > root.alarmValue ? root.powerColor : root.alarmColor
radius: batteryRect.radius
}

Text {
text: value.toString() + "%"
font.pointSize: {
var width = batteryRect.width / 5
return width > 0 ? width : 14
}
color: value > root.alarmValue ? "black" : root.alarmColor
anchors.centerIn: batteryRect
}
}

Rectangle {
width: 10
height: 20
color: root.borderColor
x: batteryRect.x + batteryRect.width
y: (root.height - height) / 2
}
}
22 changes: 22 additions & 0 deletions BatteryQuick/BatteryQuick.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
QT += quick

SOURCES += \
main.cc

resources.files = Main.qml
resources.prefix = /$${TARGET}
RESOURCES += resources

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

resources.files += \
Battery.qml
25 changes: 25 additions & 0 deletions BatteryQuick/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
qt_add_executable(BatteryQuick main.cc)

qt_add_qml_module(
BatteryQuick
URI
BatteryResources
VERSION
1.0
QML_FILES
Main.qml
Battery.qml)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. If
# you are developing for iOS or macOS you should consider setting an explicit,
# fixed bundle identifier manually though.
set_target_properties(
BatteryQuick
PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.BatteryQuick
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE)

target_link_libraries(BatteryQuick PRIVATE Qt6::Quick)
71 changes: 71 additions & 0 deletions BatteryQuick/Main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Fusion

Window {
id: root

width: 300
height: 160
visible: true
title: qsTr("Battery")

RowLayout {
spacing: 10
anchors.fill: parent

Battery {
id: battery

Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 10
value: 20
}

Slider {
id: control

Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 10
orientation: Qt.Vertical
focus: false
from: 0
to: 100
value: battery.value

onValueChanged: {
// console.log("value: " + value)
battery.value = value
}

background: Rectangle {
x: control.leftPadding + control.availableWidth / 2 - width / 2
y: control.topPadding
width: 4
height: control.availableHeight
radius: 2
color: "#21be2b"

Rectangle {
width: parent.width
height: control.visualPosition * parent.height
color: "#bdbebf"
radius: 2
}
}

handle: Rectangle {
x: control.leftPadding + control.availableWidth / 2 - width / 2
y: control.topPadding + control.visualPosition * (control.availableHeight - height)
implicitWidth: 26
implicitHeight: 26
radius: 13
color: control.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
}
}
}
23 changes: 23 additions & 0 deletions BatteryQuick/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>

auto main(int argc, char *argv[]) -> int
{
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
const QUrl url(u"qrc:/BatteryResources/Main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if ((obj == nullptr) && url == objUrl) {
QCoreApplication::exit(-1);
}
},
Qt::QueuedConnection);
engine.load(url);

return app.exec();
}
Loading

0 comments on commit e2d8bc9

Please sign in to comment.