Qt水波进度条

最近联想电脑管家进行了更新,看到界面上有个类似水波的圆形百分比进度条非常nice,就想自己尝试实现一个,效果如图:

 

主要是利用QTimer来进行水波更新以达到最终效果,核心代码如下:

void WaterProgressBar::drawProgress(QPainter *painter)
{
    int height = this-> height();
    int width = this->width();
    int side = qMin(width, height);

    //start and end
    int borderWidth = this->borderWidth + this->borderPadding;
    int startX = borderWidth;
    int startY = borderWidth;
    int endX = width - borderWidth;
    int endY = height - borderWidth;

    //calculate circle area
    side = side - borderWidth * 2;
    startX = (width - side) / 2;
    startY = (height - side) / 2;
    endX = (width + side) / 2;
    endY = (height + side) / 2;

    //calculate current value's percent
    double percent = 1 - (double)(value - minValue) / (maxValue - minValue);

    //formula: y = A * qSin(ωx + φ) + k

    //w表示周期,可以理解为水波的密度,值越大密度越大(浪越密集 ^_^),取值 密度*M_PI/宽度
    double w = waterDensity * M_PI / endX;

    //A表示振幅,可以理解为水波的高度,值越大高度越高(越浪 ^_^),取值高度的百分比
    double A = endY * waterHeight;

    //k表示y轴偏移,可以理解为进度,取值高度的进度百分比
    double k = endY * percent;

    //calculate circle area
    k = (side * percent) + startY;


    //first wave PainterPath
    QPainterPath waterPath1;
    //second wave PainterPath
    QPainterPath waterPath2;

    //move to start
    waterPath1.moveTo(startX, endY);
    waterPath2.moveTo(startX, endY);

    offset += 0.6;
    if (offset > (endX / 2)) {
        offset = 0;
    }

    for(int x = startX; x <= endX; x++) {
        //first wave YAxis
        double waterY1 = (double)(A * qSin(w * x + offset)) + k;
        //second wave YAxis
        double waterY2;
        if (reverse) {
            waterY2 = (double)(A * qSin(w * -x + offset + 10)) + k;
        } else {
            waterY2 = (double)(A * qSin(w * x + offset + (endX / 2 * w))) + k;
        }

        //如果当前值为最小值则Y轴为右下角Y轴
        if (this->value == minValue) {
            waterY1 = endY;
            waterY2 = endY;
        }

        //如果当前值为最大值则Y轴为右上角Y轴
        if (this->value == maxValue) {
            waterY1 = startY;
            waterY2 = startY;
        }

        waterPath1.lineTo(x, waterY1);
        waterPath2.lineTo(x, waterY2);
    }

    //end the PainterPath
    waterPath1.lineTo(endX, endY);
    waterPath2.lineTo(endX, endY);

    //border
    QPainterPath bigPath;
    bigPath.addEllipse(startX, startY, side, side);

    //get new waves path
    QPainterPath path;
    QColor waterColor1 = usedColor;
    waterColor1.setAlpha(100);
    QColor waterColor2 = usedColor;
    waterColor2.setAlpha(200);

    painter->save();
    painter->setPen(Qt::NoPen);

    //first wave intersected
    path = bigPath.intersected(waterPath1);
    painter->setBrush(waterColor1);
    painter->drawPath(path);

    //second wave intersected
    path = bigPath.intersected(waterPath2);
    painter->setBrush(waterColor2);
    painter->drawPath(path);

    painter->restore();
}

 全套代码链接:🍞正在为您运送作品详情

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值