Qt绘制电量图

这篇博客分享了一个使用Qt库创建的电量显示图的demo,不同于常见的进度条样式,提供了一种独特的电量展示方式。文章包括代码示例,旨在记录和分享知识,希望对读者有所帮助。
摘要由CSDN通过智能技术生成

效果图:

最近在整理代码,发现我之前做的一个demo,绘制简单的电量显示图,感觉蛮有意思的,区别于现在类似手机上进度条似的电量显示,在此分享一下,希望大家喜欢!

代码:

/**
  ******************************************************************************
  * @file       MyStoragePross
  * @author     TanChengkai
  * @version    V1.0.0
  * @date       2018/09/30
  * @brief      绘制电量的自定义类(继承自QWidget)
  * @History
    <author>     <date>      <version>     <brief>
  ******************************************************************************
*/

#ifndef MYSTORAGEPROSS_H
#define MYSTORAGEPROSS_H

#include <QWidget>
#include <QWidget>
#include <QtCore>
#include <QtGui>
#include <QLabel>
#include <QTimer>
#include <QApplication>
#include <QDesktopWidget>

#define kProgressLineWidth 5    //设置电量进度的线的宽度

#define kUserTime          1    //是否使用定时器控制进度自动从0~100

namespace Ui {
class MyStoragePross;
}

class MyStoragePross : public QWidget
{
    Q_OBJECT

public:
    explicit MyStoragePross(int w,int h,QWidget *parent = 0);
    ~MyStoragePross();

    /**
     * @brief setProgressBarValue   设置当前电量值
     * @param value
     */
    void setProgressBarValue(int value);

protected:
    void paintEvent(QPaintEvent*event);

private slots:
#if kUserTime
    void slotUpdateTimer();
#endif

private:
    Ui::MyStoragePross *ui;

    int _width;                 //宽
    int _height;                //高

    int _progressWidth;         //进度条圆直径
    int _backgroundellipseWidth;//背景圆直径

    int _currentValue;          //当前值(即当前电量)

    QLabel *dispayValueLabel;   //用于显示电量文字
    QLabel *dispayTextLabel;    //用于显示“可用电量”

#if kUserTime
    QTimer *updateTimer;        //此处为了让电量自动从0->100,添加的定时器
                                //实际使用中不需要
#endif
};

#endif // MYSTORAGEPROSS_H
#include "MyStoragePross.h"
#include "ui_MyStoragePross.h"

MyStoragePross::MyStoragePross(int w,int h,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyStoragePross)
{
    ui->setupUi(this);

    _width = w;
    _height = h;
    //设置电量圈直径是整个控件的一半大小
    _progressWidth = _width/2;
    //设置电量圈中间部分灰色圆直径是电量圈直径的3/5
    _backgroundellipseWidth = _progressWidth*3/5;
    //设置当前电量为0
    _currentValue = 0;
    //设置控件宽高
    resize(_width,_height);

    //设置控件的背景
    QString MyStorageProssObjName_ = this->objectName();
    setStyleSheet("QWidget#"+MyStorageProssObjName_+"{background-color:QColor(59,71,109);border-radius:15px;}");

    //设置显示电量值文字的样式表
    dispayValueLabel = new QLabel(this);
    dispayValueLabel->setStyleSheet("background-color:#576798;color:#00ffff");

    //设置显示“可用电量”文字的样式表
    dispayTextLabel = new QLabel(this);
    dispayTextLabel->setStyleSheet("background-color:#576798;color:#00ffff");

#if kUserTime
    updateTimer = new QTimer(this);
    updateTimer->setInterval(100);
    connect(updateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateTimer()));
    updateTimer->start();
#endif
}

MyStoragePross::~MyStoragePross()
{
#if kUserTime
    if(NULL != updateTimer)
    {
        if (updateTimer->isActive())
        {
            updateTimer->stop();
        }
        delete updateTimer;
        updateTimer = NULL;
    }
#endif
    delete ui;
}

void MyStoragePross::setProgressBarValue(int value)
{
    //对于外部输入的电量值做一个简单判断,使电量范围在0~100
    if(0 > value) {
        _currentValue = 0;
    } else if (0 <= value && value <= 100) {
        _currentValue = value;
    } else {
        _currentValue = 100;
    }
    update();
}

void MyStoragePross::paintEvent(QPaintEvent *event)
{
//    Q_UNUSED(event);
    QPainter painter(this);
    QColor usedColor(0, 255, 255);
    QColor freeColor(87, 103, 152);

    //反走样
    painter.setRenderHint(QPainter::Antialiasing);
    //使用平滑的pixmap变换算法(双线性插值算法),而不是近邻插值算法
    painter.setRenderHint(QPainter::SmoothPixmapTransform);

    //变化坐标系原点
    painter.translate(_width/2,_height/2);
    //保存坐标系(此处为中心)
    painter.save();

    //以原点为中心,顺时针旋转180度
    painter.rotate(180);
    //设置画笔颜色及粗细
    painter.setPen(QPen(usedColor, 2));
    //绘制电量已经过区域
    for (int i = 0; i < _currentValue ; ++i) {
        painter.drawLine(0, _progressWidth/2-kProgressLineWidth, 0, _progressWidth/2);
        painter.rotate(3.6);
    }
    //绘制电量未经过区域
    painter.setPen(QPen(freeColor, 2));
    for (int i = _currentValue; i < 100 ; ++i) {
        painter.drawLine(0, _progressWidth/2-kProgressLineWidth-1, 0, _progressWidth/2 - 1);
        painter.rotate(3.6);
    }

    //回到保存的坐标系原点(此处为中心)
    painter.restore();

    //变化坐标系原点(此处为原来的0,0点)
    painter.translate(-_width/2, -_height/2);

    //绘制中间灰色背景圆
    painter.setBrush(QColor(87, 103, 152));
    painter.setPen(QPen(QColor(87, 103, 152), 15));
    painter.drawEllipse(QRectF((_width/2 - _backgroundellipseWidth/2),
                               (_height/2 - _backgroundellipseWidth/2),
                               _backgroundellipseWidth,
                               _backgroundellipseWidth));

    //设置中间字体
    if (_currentValue == 0) {
        dispayValueLabel->setFont(QFont("Arial", 24));
        dispayValueLabel->setText(tr("0%"));
    }
    else {
        dispayValueLabel->setFont(QFont("Arial", 24));
        dispayValueLabel->setText(tr("%1%").arg(_currentValue));
    }
    dispayTextLabel->setFont(QFont("Arial", 12));
    dispayTextLabel->setText(tr("可用电量"));

    //根据字体设置label的坐标及大小
    QFontMetrics metrics(dispayValueLabel->font());
    int textwidth = metrics.width(dispayValueLabel->text());
    int textheight = metrics.height();
    dispayValueLabel->setGeometry((width() - textwidth)/2,
                                  (height() /*- textheight*/)/2 -10,
                                  textwidth,
                                  textheight);

    QFontMetrics metrics1(dispayTextLabel->font());
    int textwidth1 = metrics1.width(dispayTextLabel->text());
    int textheight1 = metrics1.height();
    dispayTextLabel->setGeometry((width() - textwidth1)/2,
                                  (height() /*- textheight*/)/2 -textheight1 - 15,
                                  textwidth1,
                                  textheight1);

    QWidget::paintEvent(event);
}

#if kUserTime
void MyStoragePross::slotUpdateTimer()
{
    _currentValue ++;
    if(_currentValue > 100)
    {
//        updateTimer->stop();
        _currentValue = 0;
    }
    setProgressBarValue(_currentValue);
}
#endif

结尾:

只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值