今天和大家分享一个文本风格的加载动画, 有两类,其中一个可以设置文本内容和文本颜色,演示了两份. 共三个动画, 效果如下:
一共三个文件,可以直接编译 , 如果对您有所帮助的话 , 不要忘了点赞呢.
//main.cpp
#include "LoadingAnimWidget.h"
#include <QApplication>
#include <QGridLayout>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;w.setWindowTitle("加载动画 第8季");QGridLayout * mainLayout = new QGridLayout;auto* anim1= new TextInBouncingBox("正在加载");mainLayout->addWidget(anim1,0,0);auto* anim2 = new TextInBouncingBox("正在加载中");anim2->setBoxColor("slateblue");anim2->setTextColor("white");mainLayout->addWidget(anim2,0,1);auto* anim3 = new ExpandingScroll;mainLayout->addWidget(anim3,0,2);w.setLayout(mainLayout);w.show();anim1->start();anim2->start();anim3->start();return a.exec();
}
//LoadingAnimWidget.h
#ifndef LOADINGANIMWIDGET_H
#define LOADINGANIMWIDGET_H
#include <QPropertyAnimation>
#include <QWidget>
class LoadingAnimBase:public QWidget
{Q_OBJECTQ_PROPERTY(qreal angle READ angle WRITE setAngle)
public:LoadingAnimBase(QWidget* parent=nullptr);virtual ~LoadingAnimBase();qreal angle()const;void setAngle(qreal an);
public slots:virtual void exec();virtual void start();virtual void stop();
protected:QPropertyAnimation mAnim;qreal mAngle;
};
class TextInBouncingBox:public LoadingAnimBase{//显示装在上下跳动的盒子里的字符
public:TextInBouncingBox(const QString & str,QWidget* parent = nullptr);void setTextColor(const QColor& color);void setBoxColor(const QColor& color);
protected:void paintEvent(QPaintEvent*);
private:QString mText;QColor mTextColor;QColor mBoxColor;
};
class ExpandingScroll:public LoadingAnimBase{//一个圆环转动两圈之后像卷轴一样展示"正在加载"
public:ExpandingScroll(QWidget* parent = nullptr);
protected:void paintEvent(QPaintEvent*);
};
#endif
//LoadingAnimWidget.cpp
#include "LoadingAnimWidget.h"
#include <QDebug>
#include <QPaintEvent>
#include <QPainter>
#include <QtMath>
#include <QRandomGenerator>
LoadingAnimBase::LoadingAnimBase(QWidget* parent):QWidget(parent){mAnim.setPropertyName("angle");mAnim.setTargetObject(this);mAnim.setDuration(2000);mAnim.setLoopCount(-1);//run forevermAnim.setEasingCurve(QEasingCurve::Linear);setFixedSize(200,200);mAngle = 0;
}
LoadingAnimBase::~LoadingAnimBase(){}
void LoadingAnimBase::exec(){if(mAnim.state() == QAbstractAnimation::Stopped){start();}else{stop();}
}
void LoadingAnimBase::start(){mAnim.setStartValue(0);mAnim.setEndValue(360);mAnim.start();
}
void LoadingAnimBase::stop(){mAnim.stop();
}
qreal LoadingAnimBase::angle()const{ return mAngle;}
void LoadingAnimBase::setAngle(qreal an){mAngle = an;update();
}
TextInBouncingBox::TextInBouncingBox(const QString& str,QWidget* parent ):LoadingAnimBase (parent),mText(str),mBoxColor("darkslategray"),mTextColor("yellow"){setFont(QFont("Microsoft YaHei",16,2));
}
void TextInBouncingBox::setTextColor(const QColor& color){if(mTextColor != color){mTextColor = color;update();}
}
void TextInBouncingBox::setBoxColor(const QColor& color){if(mBoxColor != color){mBoxColor = color;update();}
}void TextInBouncingBox::paintEvent(QPaintEvent*){const int len = mText.size();if(len <= 0) return;QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);QFontMetrics fm(font());const int txtH = fm.height();const int rectH = txtH + 4;const int rectW = fm.horizontalAdvance("w")+4;const qreal x = width();const qreal y = height();painter.translate(0.1*x,0.6*y);painter.setBrush(QBrush(mBoxColor));const qreal amplitude = rectH*0.3;const qreal offset = M_PI / len / 2;for(int i = 0;i < len;++i){QRectF rct( i*rectW,-rectH - amplitude*qSin(-2*M_PI / 360 * mAngle + offset*i) ,rectW,rectH);painter.setPen(Qt::NoPen);painter.drawRect(rct); //画一个小盒子painter.setPen(mTextColor);painter.drawText(rct,Qt::AlignCenter,QString(mText[i])); //画一个字符}
}ExpandingScroll::ExpandingScroll(QWidget* parent):LoadingAnimBase (parent){setFont(QFont("Microsoft YaHei",16,2));mAnim.setDuration(4000);
}void ExpandingScroll::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);qreal x = width();qreal y = height();painter.translate(x/2,y/2);painter.setBrush(Qt::NoBrush);QPen pen("black");static const qreal penWidth = 4;pen.setWidthF(penWidth);painter.setPen(pen);x -= 4;y -= 4;const auto ang = mAngle;const int arr[9] = {20,30,60,90,150,180,210,275,345};//9个时间节点,分割下面10个分支if(ang < arr[0]){//中间的竖线转变为半圆弧线const qreal h = 0.25*x;painter.drawLine(0,h/2 - ang/arr[0] * h,0,-h/2);painter.drawArc(QRectF(0,-1.5*h,2*h,2*h),180*16,-180*16*ang/arr[0]);}else if(ang < arr[1]){//半圆弧线转变为四分之一圆弧和右侧的小竖线const qreal h = 0.25*x;const qreal ratio = (ang-arr[0])/(arr[1] - arr[0]);qreal start = 180 - 90*ratio;painter.drawArc(QRectF(0,-1.5*h,2*h,2*h),start*16,-start*16);painter.drawLine(x/2,-h/2,x/2,-h/2+h/2*ratio);}else if(ang < arr[2]){//剩下的上方的四分之一圆弧转为大的下方的八分之一圆弧const qreal h = 0.25*x;const qreal ratio = (ang - arr[1]) / (arr[2] - arr[1]);qreal start = 90 - 90 * ratio;painter.drawArc(QRectF(0,-1.5*h,2*h,2*h),start*16,-start*16);painter.drawLine(x/2,-h/2,x/2,0);painter.drawArc(QRectF(-x/2,-y/2,x,y),0,-45*16*ratio);}else if(ang < arr[3]){//小竖线转为下方的大的八分之一圆弧const qreal h = x/8;qreal ratio = (ang-arr[2]) / (arr[3] - arr[2]);painter.drawLine(x/2,-h*(1-ratio),x/2,0);painter.drawArc(QRectF(-x/2,-y/2,x,y),0,-(45+45*ratio)*16);}else if(ang < arr[4]){//大圆弧转两圈qreal ratio = (ang - arr[3]) / (arr[4] - arr[3]);painter.rotate(720*ratio);painter.drawArc(QRectF(-x/2,-y/2,x,y),0,-90*16);}else if(ang < arr[5]){//大圆弧转为竖线qreal ratio = (ang-arr[4]) / (arr[5] - arr[4]);painter.drawArc(QRectF(-x/2,-y/2,x,y),-90*ratio*16,-90*(1-ratio)*16);painter.drawLine(0,y/2,0,y/2 - 0.625*ratio*y);}else if(ang < arr[6]){//竖线缩小一下qreal ratio = (ang - arr[5]) / (arr[6] - arr[5]);painter.drawLine(0,y/2 - 0.375*y*ratio,0,-0.125*y);}else if(ang < arr[7]){//展开卷轴qreal ratio = (ang - arr[6]) / (arr[7] - arr[6]);QPainterPath pp;pp.addRect(QRectF(-0.375*x*ratio,-0.125*y,0.75*x*ratio,y/4).adjusted(penWidth/-2,penWidth/-2,penWidth/2,penWidth/2));painter.setClipPath(pp);const auto rct = QRectF(-0.375*x,-0.125*y,0.75*x,y/4);painter.setBrush(QBrush("burlywood"));painter.drawRoundedRect(rct,4,4);painter.drawText(rct,Qt::AlignCenter,"正在加载");}else if(ang < arr[8]){//展示一小段时间const auto rct = QRectF(-0.375*x,-0.125*y,0.75*x,y/4);painter.setBrush(QBrush("burlywood"));painter.drawRoundedRect(rct,4,4);painter.drawText(rct,Qt::AlignCenter,"正在加载");}else{//收起卷轴qreal ratio = (ang - arr[8])/(360 - arr[8]);QPainterPath pp;pp.addRect(QRectF(-0.375*x* (1-ratio),-0.125*y,0.75*x*(1-ratio),y/4).adjusted(penWidth/-2,penWidth/-2,penWidth/2,penWidth/2));painter.setClipPath(pp);const auto rct = QRectF(-0.375*x,-0.125*y,0.75*x,y/4);painter.setBrush(QBrush("burlywood"));painter.drawRoundedRect(rct,4,4);painter.drawText(rct,Qt::AlignCenter,"正在加载");}
}