Qt之繁忙等待提示

效果图

在这里插入图片描述

实现原理

  1. QPropertyAnimation控制属性变化,QTimer也可以。
  2. 用painter进行绘制。

代码

#ifndef BUSYWIDGET_H
#define BUSYWIDGET_H

#include <QGraphicsItem>
class QPropertyAnimation;
/**
 * @brief The IconLabel class
 * 繁忙控件
 */
class BusyWidget : public QGraphicsObject
{
    Q_OBJECT
    Q_PROPERTY(int angle READ angle WRITE setAngle)
public:

    BusyWidget(QGraphicsItem *parent = nullptr);
    virtual QRectF boundingRect() const override;
    void setSize(const QSize &sz);
    //显示控件
    void showItem();
    //隐藏控件
    void hideItem();
protected:
    void setAngle(int angle);
    int angle() const;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               QWidget *widget) override;

private:
    int _angle; //
    QColor _color;
    QSize _size;
    QPropertyAnimation *_pAnimation;

};

#endif // BUSYWIDGET_H



#include "busywidget.h"
#include <QPainter>
#include <QPropertyAnimation>
#include <QDebug>

BusyWidget::BusyWidget(QGraphicsItem *parent)
    : QGraphicsObject(parent)
    , _angle(0)
{
    //创建动画
    _pAnimation = new QPropertyAnimation(this, "angle");
    //设置动画持续时间
    _pAnimation->setDuration(1000);
    //设置动画循环次数
    //永远运行,直到stop
    _pAnimation->setLoopCount(-1);
    for(int i = 0; i < 12; ++i)
    {
        //使用插值的方法,设置动画值
        //因为angle 属性是int, i自增,key对应的value正好可以全部覆盖所有值,可以看成离散动画
        //NOTE:如果设置 _pAnimation->setKeyValueAt(i/11.0, i * 30);
        //     此时key对应的value不能完全覆盖,比如key = 1 时, value可以是 0 ~ 30中任意的值
        _pAnimation->setKeyValueAt(i/11.0, i);
    }
    connect(_pAnimation, &QVariantAnimation::valueChanged,[](){
    });
    showItem();
}

QRectF BusyWidget::boundingRect() const
{
    return  QRect(0, 0, _size.width(), _size.height()).adjusted(-2, -2, 2, 2);
}

void BusyWidget::setSize(const QSize &sz)
{
    _size = sz;
}

void BusyWidget::showItem()
{
    _pAnimation->start();
    this->show();
}

void BusyWidget::hideItem()
{
    _pAnimation->stop();
    this->hide();
}

void BusyWidget::setAngle(int angle)
{
    //优化,如果更行的值为当前值,不刷新界面
    if(angle == _angle){
        return;
    }
    _angle = angle;
    update();
}

int BusyWidget::angle() const
{
    return _angle;
}

void BusyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
     int width = qMin(_size.width(), _size.height());


     painter->setRenderHint(QPainter::Antialiasing);

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

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

     for (int i=0; i < 12; i++)
     {
         QColor color = _color;
         color.setAlphaF(1.0f - (i/12.0f));
         painter->setPen(Qt::NoPen);
         painter->setBrush(color);

         painter->save();
         painter->translate(boundingRect().center());
         painter->rotate(_angle * 30.0f - i*30.0f);
         painter->drawRoundedRect(-capsuleWidth*0.5, -(innerRadius+capsuleHeight), capsuleWidth,
                                  capsuleHeight, capsuleRadius, capsuleRadius);
         painter->restore();
     }
}

参考

Qt 之 QProgressIndicator(等待提示框)

实现相关代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值