Qt自定义控件-自定义电池

Qt自定义控件-自定义电池

在这里插入图片描述

概述

通过重载paintEvent方法,实现电池外观绘制,其中的动画效果通过定义QPropertyAnimation变量实现,动画效果也可以尝试定时器实现,电池的大小根据窗口大小动态调整,支持电池颜色、动画时长等自定义,电池颜色是通过阶梯变化;具体实现如下,仁者见仁,智者见智,欢迎各位同仁不吝赐教。

源码

头文件

#ifndef QBATTERY_H
#define QBATTERY_H

#include <QWidget>
#include <QPropertyAnimation>

/**
 * 电池电量控件 作者:xujidong
 * 2022-9-5s
 *  1. 可以设置电池电池尺寸,并且电池尺寸可以跟随控件大小比例切换
 *  2. 可以设置电池电量,电池电量以动画的形式变化。
 *  3. 可以设置电量变化动画时间。
 *  2. 可设置电池电量警戒值。
 *  3. 可设置电池电量正常颜色和报警颜色。
 *  4. 可设置边框颜色。
 * 问题:
 *  1. 当直接调用设置电量属性接口,不能实现动画效果
 *  2. 还没有显示充电状态
 */


class QBattery : public QWidget
{
    Q_OBJECT

    Q_PROPERTY(double minValue READ minValue WRITE setMinValue)
    Q_PROPERTY(double maxValue READ maxValue WRITE setMaxValue)
    Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged)
    Q_PROPERTY(double warningValue READ warningValue WRITE setWarningValue)
    Q_PROPERTY(QColor warningColorStart READ warningColorStart WRITE setWarningColorStart)
    Q_PROPERTY(QColor warningColorEnd READ warningColorEnd WRITE setWarningColorEnd)
    Q_PROPERTY(QColor normalColorStart READ normalColorStart WRITE setNormalColorStart)
    Q_PROPERTY(QColor normalColorEnd READ normalColorEnd WRITE setNormalColorEnd)
    Q_PROPERTY(int animatonMsecs READ animationMsecs WRITE setAnimationMsecs);

//    Q_PROPERTY(double step READ getStep WRITE setStep)
//    Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth)
//    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 borderColor READ borderColor WRITE setBorderColor)
//    Q_PROPERTY(QColor borderColorEnd READ getBorderColorEnd WRITE setBorderColorEnd)




public:
    explicit QBattery(QWidget *parent = 0);
    ~QBattery();

protected:
    void paintEvent(QPaintEvent *);
//    void drawBorder(QPainter *painter);
//    void drawBg(QPainter *painter);
//    void drawHead(QPainter *painter);

//private slots:
//    void updateValue();

private:
    QPropertyAnimation* barreryValueAnimation;
    double mMinValue = 0;                //电池电量最小值
    double mMaxValue = 100;                //电池电量最大值
    double mWarningValue;              //电池电量警戒值

    int mBorderWidth = 0;                //边框粗细
    int mBorderRadius;               //边框圆角角度
//    int bgRadius;                   //背景进度圆角角度
//    int headRadius;                 //头部圆角角度

    int mBatteryWidth = 0;                 //电池宽度
    int mBatteryHeight = 0;                //电池高度
    int mBatteryHeadWidth = 0;             //电池柱头宽度
    int mBatteryHeadHeight = 0;             //电池柱头宽度
    int mElectricBorder;                //电量填充边界
    int mAnimationMsecs;             //电池电量动画运行时间 单位毫秒

    QColor mBorderColor;        //边框渐变颜色
    QColor mWarningColorStart;         //电池低电量时的渐变开始颜色
    QColor mWarningColorEnd;           //电池低电量时的渐变结束颜色
    QColor mNormalColorStart;        //电池正常电量时的渐变开始颜色
    QColor mNormalColorEnd;          //电池正常电量时的渐变结束颜色

    double mCurrentValue;            //当前电量
//    QRectF batteryRect;             //电池主体区域
//    QTimer *timer;                  //绘制定时器
    void setValue(const double);  //设置电池电量


public:
    double minValue()            const;
    void setMinValue(double minValue);
    double maxValue()            const;
    void setMaxValue(double maxValue);

    double value()               const;
    double warningValue()          const;


//    double getStep()                const;
//    int getBorderWidth()            const;
//    int getBorderRadius()           const;
//    int getBgRadius()               const;
//    int getHeadRadius()             const;

    QColor borderColor()    const;
    void setBorderColor(const QColor &borderColor);//设置边框颜色
//    QColor getBorderColorEnd()      const;

    //设置电池电量报警时的渐变颜色
    QColor warningColorStart()     const;
    void setWarningColorStart(const QColor &warningColorStart);
    QColor warningColorEnd()       const;
    void setWarningColorEnd(const QColor &warningColorEnd);


    QColor normalColorStart()    const;
    void setNormalColorStart(const QColor &normalColorStart);
    QColor normalColorEnd()      const;
    void setNormalColorEnd(const QColor &normalColorEnd);

    int animationMsecs()     const;
    void setAnimationMsecs(const int animationMsecs);

//    QSize sizeHint()                const;
//    QSize minimumSizeHint()         const;

public Q_SLOTS:
//    //设置范围值
//    void setRange(double minValue, double maxValue);
//    void setRange(int minValue, int maxValue);



//    //设置电池电量值
    void setElecValue(int value);
    void setElecValue(double value);


    //设置电池电量警戒值
    void setWarningValue(double);
    void setWarningValue(int warningValue);

//    //设置步长
//    void setStep(double step);
//    void setStep(int step);

//    //设置边框粗细
//    void setBorderWidth(int borderWidth);
//    //设置边框圆角角度
//    void setBorderRadius(int borderRadius);
//    //设置背景圆角角度
//    void setBgRadius(int bgRadius);
//    //设置头部圆角角度
//    void setHeadRadius(int headRadius);


//    void setBorderColorEnd(const QColor &borderColorEnd);




Q_SIGNALS:
    void valueChanged(double value);

};

#endif // QBATTERY_H

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
源文件

#include "qbattery.h"
#include <QTimer>
#include <QPainter>
#include <QPen>


QBattery::QBattery(QWidget *parent)
{
    mBorderColor = QColor(100, 100, 100);
    mNormalColorStart = QColor(50, 205, 51);        //电池正常电量时的渐变开始颜色
    mNormalColorEnd = QColor(60, 179, 133);          //电池正常电量时的渐变结束颜色
    mWarningColorStart = QColor(250, 118, 113);
    mWarningColorEnd = QColor(204, 38, 38);


    mBorderRadius = 1;
    mBorderWidth = 2;
    mBatteryHeadWidth = 6;
    mBatteryHeadHeight = 20;
    mBatteryWidth = 80;
    mBatteryHeight = 40;
    mElectricBorder = 2;
    mWarningValue = 20.0;
    mCurrentValue = 60.0;

    mAnimationMsecs = 500; //动画运行时间,单位微妙

    barreryValueAnimation = new QPropertyAnimation(this,"value");
}

QBattery::~QBattery()
{
    delete barreryValueAnimation;
}

void QBattery::paintEvent(QPaintEvent *paintEvent)
{
    Q_UNUSED(paintEvent)
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing); //设置抗锯齿

    int batteryWidth = mBatteryWidth + mBatteryHeadWidth + 3*mBorderWidth; //计算电池总体的长和宽
    int batteryHeight = mBatteryHeight +2*mBorderWidth;
    float ratioX = (float)width()/batteryWidth;         //计算电池与实际窗口的长宽比
    float ratioY = (float)height()/batteryHeight;
    int windowWidth;
    int windowHeight;

    //根据窗口缩放,计算实际缩放后的窗口大小
    if(ratioX > ratioY){
        windowWidth = batteryWidth*ratioY;
        windowHeight = height();
    }else{
        windowWidth = width();
        windowHeight = batteryHeight*ratioX;
    }

    //计算窗口缩放后的电池的长宽等数据
    float ratio = qMin(ratioX,ratioY);
    int ratioWidth = mBatteryWidth*ratio;
    int ratioHeight = mBatteryHeight*ratio;
    int ratioBorderWidth = mBorderWidth*ratio;
    int ratioBatteryHeadWidth = mBatteryHeadWidth*ratio;
    int ratioBatteruHeadHeight = mBatteryHeadHeight*ratio;
    int ratioElectricBorder = mElectricBorder*ratio;

    painter.setViewport(0,0,windowWidth,windowHeight);  //设置视图窗口
    painter.setWindow(-windowWidth/2,-windowHeight/2,windowWidth,windowHeight);//设置窗口坐标原点为视口区域
                                                                               //的中心,只有视图坐标尺寸和窗口坐标尺寸比例相同时,才不会导致图形拉伸变形


    //绘制电池轮廓
    QPen pen;
    pen.setWidth(ratioBorderWidth);
    pen.setColor(mBorderColor);
    painter.setPen(pen);
    painter.drawRect(-ratioWidth/2,-ratioHeight/2,ratioWidth,ratioHeight);

    //绘制电池正极
    QBrush brush;
    brush.setColor(mBorderColor);
    brush.setStyle(Qt::SolidPattern); //画刷填充样式
    painter.setBrush(brush);
    painter.drawRect(ratioWidth/2,-ratioBatteruHeadHeight/2,ratioBatteryHeadWidth,ratioBatteruHeadHeight);

    //填充电池颜色
    painter.setPen(Qt::NoPen);
    QLinearGradient linearGradient(-ratioWidth/2+ratioElectricBorder,-ratioHeight/2+ratioElectricBorder,
                                   -ratioWidth/2+ratioElectricBorder,
                                   -ratioHeight/2+ratioElectricBorder+ratioHeight-2*ratioElectricBorder);
//    brush.setStyle(Qt::CrossPattern); //画刷填充样式

    if(mCurrentValue > mWarningValue){
        linearGradient.setColorAt(0,mNormalColorStart);
        linearGradient.setColorAt(1,mNormalColorEnd);
        brush.setStyle(Qt::LinearGradientPattern);
        painter.setBrush(linearGradient);
        painter.drawRect(-ratioWidth/2+ratioElectricBorder,-ratioHeight/2+ratioElectricBorder,
                         mCurrentValue/100*(ratioWidth-2*ratioElectricBorder),ratioHeight-2*ratioElectricBorder);
    }else{
        linearGradient.setColorAt(0,mWarningColorStart);
        linearGradient.setColorAt(1,mWarningColorEnd);
        painter.setBrush(linearGradient);
        painter.drawRect(-ratioWidth/2+ratioElectricBorder,-ratioHeight/2+ratioElectricBorder,
                         mCurrentValue/100*(ratioWidth-2*ratioElectricBorder),ratioHeight-2*ratioElectricBorder);
    }

    //绘制电池电量文字
    QFont font = this->font();
    qDebug()<<"font.pixelSize = "<<font.pixelSize();
    font.setPixelSize(10*ratio);
    this->setFont(font);
    QFontMetrics textSize = QWidget::fontMetrics();
    qDebug()<<"textSize.height() = "<<textSize.height()<<"textSize.maxWidth()"<<textSize.maxWidth();
    QString powStr=QString::asprintf("%.2f%%",mCurrentValue);
    QRect textRect=textSize.tightBoundingRect(powStr);//得到字符串的rect

    pen.setColor("black"); //划线颜色
    painter.setPen(pen);
    painter.drawText(0-textRect.width()/2,textRect.height()/2,powStr);
}


double QBattery::value() const
{
    return mCurrentValue;
}


void QBattery::setValue(const double value)
{
    mCurrentValue = value;
    this->repaint();
}

double QBattery::minValue() const
{
    return mMinValue;
}

void QBattery::setMinValue(double minValue)
{
    mMinValue = minValue;
}

double QBattery::maxValue() const
{
    return mMaxValue;
}

void QBattery::setMaxValue(double maxValue)
{
    mMaxValue = maxValue;
}


void QBattery::setElecValue(int value)
{
    barreryValueAnimation->setDuration(mAnimationMsecs);
    barreryValueAnimation->setStartValue(mCurrentValue);
    barreryValueAnimation->setEndValue((double)value);
    barreryValueAnimation->start();
}

void QBattery::setElecValue(double value)
{
    barreryValueAnimation->setDuration(mAnimationMsecs);
    barreryValueAnimation->setStartValue(mCurrentValue);
    barreryValueAnimation->setEndValue(value);
    barreryValueAnimation->start();
}

double QBattery::warningValue() const
{
    return mWarningValue;
}


void QBattery::setWarningValue(double warningValue)
{
    mWarningValue = warningValue;
    this->repaint();
}

void QBattery::setWarningValue(int warningValue)
{
    mWarningValue = (double)warningValue;
    this->repaint();
}

QColor QBattery::borderColor() const
{
    return mBorderColor;
}

void QBattery::setBorderColor(const QColor &borderColor)
{
    mBorderColor = borderColor;
    this->repaint();
}

QColor QBattery::warningColorStart() const
{
    return mWarningColorStart;
}

void QBattery::setWarningColorStart(const QColor &warningColorStart)
{
    mWarningColorStart = warningColorStart;
    this->repaint();
}

QColor QBattery::warningColorEnd() const
{
    return mWarningColorEnd;
}

void QBattery::setWarningColorEnd(const QColor &warningColorEnd)
{
    mWarningColorEnd = warningColorEnd;
    this->repaint();
}

QColor QBattery::normalColorStart() const
{
    return mNormalColorStart;
}

void QBattery::setNormalColorStart(const QColor &normalColorStart)
{
    mNormalColorStart = normalColorStart;
    this->repaint();
}

QColor QBattery::normalColorEnd() const
{
    return mNormalColorEnd;
}

void QBattery::setNormalColorEnd(const QColor &normalColorEnd)
{
    mNormalColorEnd = normalColorEnd;
    this->repaint();
}

int QBattery::animationMsecs() const
{
    return mAnimationMsecs;
}

void QBattery::setAnimationMsecs(const int animationMsecs)
{
    mAnimationMsecs = animationMsecs;
    this->repaint();
}
#endif

功能持续更新中。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jkdon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值