Qt自定义进度条

标签: qt  自定义控件  进度条

瞎扯

转眼已经折腾Qt(画图软件23333)快5个月了,C++的东西没学到多少,各种软件绘图技巧倒是折腾了不少。在刚开始工作的时候看到设计稿的软件界面还是一脸懵逼的,现在发现没有什么是Qt的paint()和PS解决不了的,如果有,再加个Ae~ o( ̄▽ ̄)ブ
另外,现在CSDN真恶心,还清除以前的积分ε=( o`ω′)ノ

简介

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

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

各种进度条

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

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

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();
}

相关资源

源码在这里->点击下载~

版权声明:本文为u013743026原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013743026/article/details/78715953

智能推荐

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

猜你喜欢

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...

OpenStack代码贡献初体验

为什么80%的码农都做不了架构师?>>>     OpenStack如今已成为开源云平台中的明星项目,得到广泛关注。OpenStack的优秀出众依赖于众多开发者的努力,在享受其带来的便利与快捷的同时,为其做一份贡献也是一个开发者的义务。  在前段时间的OpenStack的测试过程中,我发现Nova项目中的一个Bug,于是向社区提交了Bug报...

SQL Server之8:sql查询每个学生得分最高的两门课

这是一道面试题,今天有空把它记下来,以后遇到此类问题作个参考!刚一看到这个题目,估计好多人都会想到关键字top,其实这里用到的关键字是partition, 好了,先看看表结构,及数据吧!     接下来看一看partition的功能,执行语句   结果如下:   到这里一目了然知道最终结果了!   View Code     &...