使用 qt的Widget组件画圆环进度条
1.需要创建一个圆环类,继承QWidget
#ifndef CIRCULARPROGRESS_H
#define CIRCULARPROGRESS_H
#include <QWidget>
#include <QPainter>
#include <QTime>
//圆环进度类
class CircularProgress : public QWidget
{
Q_OBJECT
public:
explicit CircularProgress(QWidget *parent = nullptr);
~CircularProgress();
int getVal();
int getTargeVal();
void setTargetVal(int val);
//设置进度条初始范围值
void setPlanVal(int val, int min , int max);
//设置圆环显示的模式
void setShowMode(bool mode);
//圆环大小
//void setCircleSizo(int x, int y);
//圆环宽度
void setWide(int wide);
//设置单色进度条颜色
void setPlanOneColor(Qt::GlobalColor base ,Qt::GlobalColor now);
//渐变进度条
void setPlanAtColor(Qt::GlobalColor base ,Qt::GlobalColor at_0, Qt::GlobalColor at_1);
//设置圆环中心显示
void setMiddleShow( Qt::GlobalColor base_c ,Qt::GlobalColor font_c,int font_size,QString str );
void setUpdataShow(){
update();
};
signals:
protected:
void paintEvent(QPaintEvent *e);
private:
void drawCirculaProgess(QPainter *p);//画圆环
void timerTargetUpdateShow();
private:
//
// int c_fixedSize_h;// 外圆大小,使用UI时设计好大小
// int c_fixedSize_d;// 外圆大小,使用UI时设计好大小
int c_wide;//圆环宽度
// 进度条百分百数值范围
int m_val = 0 ;//当前值
int m_min = 0 ;//最小值
int m_max = 100 ;//最大值
int m_target_val = 0;//目标值
//
bool c_mode;//0不渐变,1 渐变
Qt::GlobalColor c_plan_base;//圆环进度底色
Qt::GlobalColor c_plan_one;//进度条显示颜色
Qt::GlobalColor c_plan_at_0;//渐变色0
Qt::GlobalColor c_plan_at_1;//渐变色1
Qt::GlobalColor c_mid_base;//中间底色
Qt::GlobalColor c_mid_font;//中间显示字体颜色
int c_mid_font_size;//字体大小
QString c_mid_str_flag;//单位显示 “% ,°C ,kg”
//
QTimer *timer;//定时器,匀速递增减
};
#endif // CIRCULARPROGRESS_H
2.源文件,封装一些简单的设置
#include "circularprogress.h"
#include <QDebug>
#include <QColor>
#include <QTimer>
CircularProgress::CircularProgress(QWidget *parent) : QWidget(parent)
{
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &CircularProgress::timerTargetUpdateShow);
}
CircularProgress::~CircularProgress()
{
}
int CircularProgress::getVal()
{
return m_val;//获取当前值
}
int CircularProgress::getTargeVal()
{
return m_target_val;//获取当前值
}
void CircularProgress::setTargetVal(int val)
{
timer->stop();
if(val > m_max) {
m_target_val = m_max;
}
else if(val < m_min){
m_target_val = m_min;
}
else{
m_target_val = val;
}
if(m_target_val != m_val)
{
timer->start(2);
}
// update();//更新,重绘圆环
}
void CircularProgress::timerTargetUpdateShow()
{
if(m_target_val != m_val)
{
if(m_target_val > m_val)
{
m_val++;
}
else
{
m_val--;
}
}
else
{
timer->stop();
}
update();//更新,重绘圆环
}
void CircularProgress::setPlanVal(int val, int min, int max){
m_val = val ;
m_min = min;
m_max = max;
}
void CircularProgress::setShowMode(bool mode)
{
c_mode = mode ;
}
void CircularProgress::setWide(int wide)
{
c_wide = wide;
}
void CircularProgress::setPlanOneColor(Qt::GlobalColor base, Qt::GlobalColor now)
{
c_plan_base = base;
c_plan_one = now;
}
void CircularProgress::setPlanAtColor(Qt::GlobalColor base, Qt::GlobalColor at_0, Qt::GlobalColor at_1)
{
c_plan_base = base;
c_plan_at_0 = at_0;
c_plan_at_1 = at_1;
}
void CircularProgress::setMiddleShow(Qt::GlobalColor base_c, Qt::GlobalColor font_c, int font_size, QString str)
{
c_mid_base = base_c;
c_mid_font = font_c;
c_mid_font_size = font_size;
c_mid_str_flag = str;
}
void CircularProgress::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
QPainter painter(this);
//设置抗锯齿
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
drawCirculaProgess(&painter);
}
void CircularProgress::drawCirculaProgess(QPainter *p)
{
//1.实心圆
p->setPen( Qt::NoPen );
p->setBrush( c_plan_base );//进度条底色
p->drawEllipse( this->rect() );//根据矩形大小画圆
//2.画伞型
if(c_mode == 0)//单色
{
p->setBrush( c_plan_one );//单色
}
else//渐变
{
QConicalGradient coni( rect().center(), 90 );//渐变色
coni.setColorAt(0, QColor( c_plan_at_1 ));// 结束颜色
coni.setColorAt(1.0, QColor( c_plan_at_0 ));//起始颜色
p->setBrush(coni );//
}
//3.计算伞型覆盖角度
p->drawPie( rect() , 90*16 , - m_val *1.0 / (m_max - m_min) * 360 *16 );
//4.制作圆环,获取当前矩形大小,缩小50像素
p->setBrush(c_mid_base);//中心圆颜色
QRect minRect = this->rect().adjusted(c_wide,c_wide,-c_wide,-c_wide);
p->drawEllipse(minRect);//绘制伞型
//在中心显示字体
p->setPen( QPen( c_mid_font));//颜色
QFont font = p->font();//字体设置
font.setPixelSize(c_mid_font_size);//字体大小
p->setFont( font );
p->drawText( this->rect(),Qt::AlignCenter,QString::number(m_val) + c_mid_str_flag);
}
3.核心代码
void CircularProgress::drawCirculaProgess(QPainter *p)
{
//1.实心圆
p->setPen( Qt::NoPen );
p->setBrush( c_plan_base );//进度条底色
p->drawEllipse( this->rect() );//根据矩形大小画圆
//2.画伞型
if(c_mode == 0)//单色
{
p->setBrush( c_plan_one );//单色
}
else//渐变
{
QConicalGradient coni( rect().center(), 90 );//渐变色
coni.setColorAt(0, QColor( c_plan_at_1 ));// 结束颜色
coni.setColorAt(1.0, QColor( c_plan_at_0 ));//起始颜色
p->setBrush(coni );//
}
//3.计算伞型覆盖角度
p->drawPie( rect() , 90*16 , - m_val *1.0 / (m_max - m_min) * 360 *16 );
//4.制作圆环,获取当前矩形大小,缩小50像素
p->setBrush(c_mid_base);//中心圆颜色
QRect minRect = this->rect().adjusted(c_wide,c_wide,-c_wide,-c_wide);
p->drawEllipse(minRect);//绘制伞型
//在中心显示字体
p->setPen( QPen( c_mid_font));//颜色
QFont font = p->font();//字体设置
font.setPixelSize(c_mid_font_size);//字体大小
p->setFont( font );
p->drawText( this->rect(),Qt::AlignCenter,QString::number(m_val) + c_mid_str_flag);
}
//----------------------------------------------------------------------
代码写好后,直接调用就行了
调用有两种方式,
1.直接new一个CircularProgress,然后设置大小和位置。
2.在ui页面拉一个widget组件,然后提升为CircularProgress类
大小和位置直接在ui设计窗口就能设置,比较方便,本次实验就是这种方式。
然后在主页面调用
void mainWidget::spineInit()
{
ui->c_spine_1->setShowMode(1);
ui->c_spine_1->setWide(8);
ui->c_spine_1->setPlanVal( 0,0,100 );
//ui->c_spine_1->setPlanOneColor(Qt::gray,Qt::blue);
ui->c_spine_1->setPlanAtColor(Qt::gray, Qt::green ,Qt::red);
ui->c_spine_1->setMiddleShow(Qt::white , Qt::black, 12 , " %");
ui->c_spine_1->setUpdataShow();
ui->c_spine_2->setShowMode(0);
ui->c_spine_2->setWide(8);
ui->c_spine_2->setPlanVal( 40,0,100 );
ui->c_spine_2->setPlanOneColor(Qt::gray,Qt::blue);
ui->c_spine_2->setMiddleShow(Qt::white , Qt::black, 15 , " %");
ui->c_spine_2->setUpdataShow();
}
运行效果显示
//简单使用环形进度条显示完成。