Qt 简约美观的加载动画 文本风格 第八季

今天和大家分享一个文本风格的加载动画, 有两类,其中一个可以设置文本内容和文本颜色,演示了两份. 共三个动画, 效果如下:

一共三个文件,可以直接编译 , 如果对您有所帮助的话 , 不要忘了点赞呢.

cpp 复制代码
//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();
}
cpp 复制代码
//LoadingAnimWidget.h
#ifndef LOADINGANIMWIDGET_H
#define LOADINGANIMWIDGET_H
#include <QPropertyAnimation>
#include <QWidget>
class LoadingAnimBase:public QWidget
{
    Q_OBJECT
    Q_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
cpp 复制代码
//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 forever
    mAnim.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,"正在加载");
    }
}
相关推荐
Re.不晚14 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会17 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香19 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??23 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
远望清一色39 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man1 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*1 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家1 小时前
go语言中package详解
开发语言·golang·xcode