鱼C论坛

 找回密码
 立即注册
查看: 6245|回复: 0

[技术原创] 菊花旋转完全用代码实现圆形加载进度动画 - C/C++进阶之Qt图形UI库

[复制链接]
发表于 2017-3-27 14:26:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
简述

初尝QT不甚欢喜,鱼C上有许多的朋友在为QT做出贡献,我也愿意以主观角度来分享QT,让QT变得更好。
该源码系作者个人撰写,使用时请尊重作者,不要随意篡改关于作者的信息。
版权所有:CSND_Ayo,转载请注明出处:http://blog.csdn.net/csnd_ayo

原帖地址:http://blog.csdn.net/csnd_ayo/article/details/56486455

源码
#ifndef CUSTOMPROGRESSINDICATOR_H
#define CUSTOMPROGRESSINDICATOR_H

#include <QWidget>
#include <QColor>
/*
* 菊花转 进度类,基于代码无需图片资源
* 作者:陈鲁勇
* 邮箱:727057301@qq.com
* 创建时间:2017年2月10日16:26:48
* QT版本:5.0.2
* CSDN:http://blog.csdn.net/csnd_ayo 
* **************************************
* 说明:
*   使用前请确保在QT.pro中加入 C++11 的支持
*
* 示例代码:

    pIndicator = new CustomProgressIndicator(this);
    pIndicator->setColor(Qt::red);
    pIndicator->startAnimation();
*/

class CustomProgressIndicator : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
    Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
    Q_PROPERTY(QColor color READ color WRITE setColor)
public:
    CustomProgressIndicator(QWidget* parent = 0);

    int animationDelay() const { return delay_; }

    /*  动画是否正在进行中  */
    bool isAnimated () const;

    /*  动画完毕后,是否隐藏菊花转  */
    bool isDisplayedWhenStopped() const;

    /*  当前菊花转的颜色  */
    const QColor & color() const { return color_; }

    /*  虚函数:当前大小  */
    virtual QSize sizeHint() const;

    void setBackground(const QString& _icon) {
        currentPix_ = QPixmap(_icon);
    }
signals:
    void Finished(void);
public slots:

    /*  开始动画  */
    void startAnimation();

    /*  停止动画  */
    void stopAnimation();

    /*  设置菊花转的转速  */
    void setAnimationDelay(int delay);

    /*  动画完毕后,是否隐藏菊花转  */
    void setDisplayedWhenStopped(bool state);

    /*  设置菊花转颜色  */
    void setColor(const QColor & color);

    /*
     * 进度
     * 参数 _progress:当前进度 0 < _progress < 100
    */
    void onProgress(short _progress) { progress_ = _progress; }
protected:
    /*  系统基类函数 */
    virtual void timerEvent(QTimerEvent * event);
    virtual void paintEvent(QPaintEvent * event);
private:
    /*  角度  */
    unsigned int angle_;
    /*  定时器ID  */
    int timerId_;
    /*  转速  */
    int delay_;
    /*  是否隐藏  */
    bool displayedWhenStopped_;
    /*  菊花转颜色  */
    QColor color_;
    /*  进度  */
    short progress_;
    /*  背景图  */
    QPixmap currentPix_;
};


#endif // CUSTOMPROGRESSINDICATOR_H

#include "customprogressindicator.h"
#include <QPainter>

CustomProgressIndicator::CustomProgressIndicator(QWidget* parent)
    : QWidget(parent),
      angle_(0),
      timerId_(-1),
      delay_(20),
      displayedWhenStopped_(false),
      color_(Qt::green) {
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    setFocusPolicy(Qt::NoFocus);
}

bool CustomProgressIndicator::isAnimated () const {
    return (timerId_ != -1);
}

void CustomProgressIndicator::setDisplayedWhenStopped(bool state) {
    displayedWhenStopped_ = state;

    update();
}

bool CustomProgressIndicator::isDisplayedWhenStopped() const {
    return displayedWhenStopped_;
}

void CustomProgressIndicator::startAnimation() {
    angle_ = 0;

    if (timerId_ == -1) {
       timerId_ = startTimer(delay_);
    }
}

void CustomProgressIndicator::stopAnimation() {
    if (timerId_ != -1) {
        killTimer(timerId_);
    }

    timerId_ = -1;

    update();
}

void CustomProgressIndicator::setAnimationDelay(int delay) {
    if (timerId_ != -1){
        killTimer(timerId_);
    }

    delay_ = delay;

    if (timerId_ != -1){
        timerId_ = startTimer(delay_);
    }
}

void CustomProgressIndicator::setColor(const QColor & color) {
    color_ = color;

    update();
}

QSize CustomProgressIndicator::sizeHint() const {
    return QSize(25,25);
}


void CustomProgressIndicator::timerEvent(QTimerEvent * /*event*/) {
    angle_ = (angle_+30)%360;

    update();
}

void CustomProgressIndicator::paintEvent(QPaintEvent * /*event*/) {
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);
    if (!displayedWhenStopped_ && !isAnimated()) {
        p.drawPixmap(rect(),currentPix_);
        return;
    }

    int width = qMin(this->width(), this->height());


    int outerRadius = (width-1) >> 1;
    int innerRadius = ((width-1) >> 1)*0.38;

    int capsuleHeight = outerRadius - innerRadius;
    int capsuleWidth  = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35;
    int capsuleRadius = capsuleWidth >> 1;

    /* 撰写进度 */
    if (progress_ > 0 && progress_ < 100) {
        p.setPen(color_);
        p.drawText(rect(), Qt::AlignCenter, QString("%1%").arg(progress_));
    }
    else if (progress_ == 100) {
        stopAnimation();
    }

    for (int i=0; i<12; ++i) {
        QColor color = color_;
        color.setAlphaF(1.0f - (i/12.0f));
        p.setPen(Qt::NoPen);
        p.setBrush(color);
        p.save();
        p.translate(rect().center());
        p.rotate(angle_ - i*30.0f);
        p.drawRoundedRect(((-capsuleWidth) >> 1), -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
        p.restore();
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 13:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表