Qt自定义进度条

简介

在需要按比例显示数据的时候,进度条是必不可少的。Qt中有一个进度条相关的类QProgressBar,这个类提供了简单的水平或垂直的进度条,可以通过修改qss简单的改变下样式:

简单使用的话自带的样式就够看了,但是也有时候设计非要搞些酷炫的效果,没办法只能折腾下了......比如,设计稿非要整个两端椭圆的进度条,qss就没辙了。这篇文章主要总结下Qt在绘制控件方面的经验,画都能画出来了,其他骚操作就随便搞了,下面是折腾出来的栗子:

各种进度条

各种进度条

重绘paint之两端圆角进度条(继承QProgressbar)

图中第一个,其实也可以直接继承QWidget的,就少写个设置百分比和最小最大值的函数,主要还是重写paint函数,画出进度条底图和根据当前value值画出蓝色进度条:

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

void RadiusProgressBar::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    QRect rect = QRect(0, 0, width(), height()/2);
    QRect textRect = QRect(0, height()/2, width(), height()/2);

    const double k = (double)(value() - minimum()) / (maximum()-minimum());
    int x = (int)(rect.width() * k);
    QRect fillRect = rect.adjusted(0, 0, x-rect.width(), 0);

    QString valueStr = QString("%1%").arg(QString::number(value()));
    QPixmap buttomMap = QPixmap(":/resource/radius_back.png");
    QPixmap fillMap = QPixmap(":/resource/radius_front.png");

    //画进度条
    p.drawPixmap(rect, buttomMap);
    p.drawPixmap(fillRect, fillMap, fillRect);

    //画文字
    QFont f = QFont("Microsoft YaHei", 15, QFont::Bold);
    p.setFont(f);
    p.setPen(QColor("#555555"));
    p.drawText(textRect, Qt::AlignCenter, valueStr);
}

重绘paint之纯色圆环进度条(继承QWidget)

图中第二个,这是单纯用程序画出来的,没有贴图,在画出底图的圆以及上层的圆弧后,在上层再画一个透明的圆,相当于遮罩:

void RingsProgressbar::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);

    m_rotateAngle = 360*m_persent/100;

    int side = qMin(width(), height());
    QRectF outRect(0, 0, side, side);
    QRectF inRect(20, 20, side-40, side-40);
    QString valueStr = QString("%1%").arg(QString::number(m_persent));

    //画外圆
    p.setPen(Qt::NoPen);
    p.setBrush(QBrush(QColor(97, 117, 118)));
    p.drawEllipse(outRect);
    p.setBrush(QBrush(QColor(255, 107, 107)));
    p.drawPie(outRect, (90-m_rotateAngle)*16, m_rotateAngle*16);
    //画遮罩
    p.setBrush(palette().window().color());
    p.drawEllipse(inRect);
    //画文字
    QFont f = QFont("Microsoft YaHei", 15, QFont::Bold);
    p.setFont(f);
    p.setFont(f);
    p.setPen(QColor("#555555"));
    p.drawText(inRect, Qt::AlignCenter, valueStr);
}

重绘paint之贴图圆环进度条(继承QWidget)

图中第三个,在玩第二种进度条的时候,意外发现drawPie()设置笔刷后可以直接画圆弧,这种骚操作 不试试还真不知道:

void RingsMapProgressbar::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);

    m_rotateAngle = 360*m_persent/100;

    int side = qMin(width(), height());
    QRectF outRect(0, 0, side, side);
    QRectF inRect(20, 20, side-40, side-40);
    QString valueStr = QString("%1%").arg(QString::number(m_persent));

    //画底圆
    p.setPen(Qt::NoPen);
    QPixmap backMap = QPixmap(":/resource/progress_back.png");
    p.drawPixmap(outRect, backMap, outRect);
    //画内弧
    QPixmap frontMap = QPixmap(":/resource/progress_front.png");
    p.setBrush(QBrush(frontMap));
    p.drawPie(outRect, (90-m_rotateAngle)*16, m_rotateAngle*16);
    //画文字
    QFont f = QFont("Microsoft YaHei", 15, QFont::Bold);
    p.setFont(f);
    p.setPen(QColor("#DDDDDD"));
    p.drawText(inRect, Qt::AlignCenter, valueStr);
}

重绘paint之属性动画进度条(继承QWidget)

图中第4个,上面3个都是用程序控制显示进度的,最后一个是直接将进度条动画导出成序列帧图片,播放动画的形式来画进度条。这种方式主要是在某些等待操作以及需要进度条动画有曲线的时候用的,前提是你要会做动画和导出序列帧哦(⊙o⊙):

AnimationProgressbar::AnimationProgressbar(QWidget *parent) : QWidget(parent),
    m_animaindex(0),
    m_animaTotal(30),
    m_persent(0)
{
    QPixmap aniMap(":/resource/sequence_animate.png");

    for(int i=0; i<m_animaTotal; i++){
        m_animalist << aniMap.copy(i*(aniMap.width()/m_animaTotal), 0, aniMap.width()/m_animaTotal, aniMap.height());
    }

    m_animation=new QPropertyAnimation(this,"");
    m_animation->setStartValue(0);
    m_animation->setEndValue(m_animaTotal - 1);
    m_animation->setDuration(2000);
    m_animation->setLoopCount(-1);
    connect(m_animation,SIGNAL(valueChanged(QVariant)),this,SLOT(slot_valuechange(QVariant)));
}

void AnimationProgressbar::startAnimation()
{
    update();

    m_animation->start();
}

void AnimationProgressbar::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    p.setRenderHint(QPainter::SmoothPixmapTransform);

    int side = qMin(width(), height());
    QRect outRect(0, 0, side, side);
    QRect inRect(20, 20, side-40, side-40);
    QString valueStr = QString("%1%").arg(QString::number(m_persent));

    //画圆环
    p.drawPixmap(outRect, m_animalist.at(m_animaindex));

    //画文字
    QFont f = QFont("Microsoft YaHei", 15, QFont::Bold);
    p.setFont(f);
    p.setPen(QColor("#555555"));
    p.drawText(inRect, Qt::AlignCenter, valueStr);
}

void AnimationProgressbar::slot_valuechange(QVariant var)
{
    m_animaindex = var.toInt();
    m_persent = m_animaindex*100 / m_animaTotal;

    update();
}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值