Qt繪製電量圖

效果圖:

最近在整理代碼,發現我之前做的一個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

結尾:

只爲記錄,只爲分享! 願所寫能對你有所幫助。不忘記點個贊,謝謝~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章