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

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

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

//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_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
//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,"正在加载");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/424225.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Github 2024-03-03 开源项目日报Top9

根据Github Trendings的统计&#xff0c;今日(2024-03-03统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量非开发语言项目4Rust项目1C项目1Jupyter Notebook项目1Python项目1Shell项目1 任天堂Switch模拟器yuzu&#x…

13-微服务初探-自研微服务框架

微服务初探 1. 架构变迁之路 1.1 单体架构 互联网早期&#xff0c;一般的网站应用流量较小&#xff0c;只需要一个应用&#xff0c;将所有的功能代码都部署在一起就可以&#xff0c;这样可以减少开发&#xff0c;部署和维护的成本。 比如说一个电商系统&#xff0c;里面包含…

【每日刷题】数组-LC56、LC238、随想录1、LC560

1. LC56 合并区间 题目链接 Arrays.sort先让intervals里的子数组按照子数组的第一个数字值从小到大排列。开一个新数组&#xff0c;newInterval&#xff0c;存放合并好的子数组让intervals的当前子数组i的第一个数字与newInterval的当前子数组index的最后一个数字比较大小&am…

2024 年适用于电脑的十大录制屏幕软件

录制屏幕软件的设计和开发旨在让您的工作流程更轻松、更高效。这些漂亮的工具有助于为教育目的捕获图像快照或记录屏幕以与客户共享模型。无论您寻找桌面屏幕录像机的原因是什么&#xff0c;这里都有最好的付费和免费实用程序。该类别中我们最喜欢的一些选择是 奇客录屏助手和 …

docker 转为docker-compose(composerize 命令)

可以使用Composerize将Docker命令转换为Docker Compose文件。 例如&#xff1a;将docker run命令转换为Docker Compose格式&#xff0c;只需用Composerize运行它&#xff0c;如下所示&#xff1a; composerize docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/…

IDEA的安装教程

1、下载软件安装包 官网下载&#xff1a;https://www.jetbrains.com/idea/ 2、开始安装IDEA软件 解压安装包&#xff0c;找到对应的idea可执行文件&#xff0c;右键选择以管理员身份运行&#xff0c;执行安装操作 3、运行之后&#xff0c;点击NEXT&#xff0c;进入下一步 4、…

美团分布式 ID 框架 Leaf 介绍和使用

一、Leaf 在当今日益数字化的世界里&#xff0c;软件系统的开发已经成为了几乎所有行业的核心。然而&#xff0c;随着应用程序的规模不断扩大&#xff0c;以及对性能和可扩展性的需求不断增加&#xff0c;传统的软件架构和设计模式也在不断地面临挑战。其中一个主要挑战就是如…

凌特杯,第二届,数字音频传输。simulink matlab

终于比赛进入了尾声&#xff0c;最为指导老师也是非常的激动。接下来进入了论文写作阶段和视频拍摄阶段。 第二届凌特杯规定的硬件是ADI的Pluto&#xff0c;成本在2k以内&#xff0c;能支持MATLAB&#xff0c;它能够流畅的实时播放接收到的音乐数据&#xff0c;并把数据保存成…

图论例题解析

1.图论基础概念 概念 &#xff08;注意连通非连通情况&#xff0c;1节点&#xff09; 无向图&#xff1a; 度是边的两倍&#xff08;没有入度和出度的概念&#xff09; 1.完全图&#xff1a; 假设一个图有n个节点&#xff0c;那么任意两个节点都有边则为完全图 2.连通图&…

Mysql列子查询

目录 列子查询数据准备 列子查询 子查询返回的结果是一列(可以是多行)&#xff0c;这种子查询称为列子查询。 常用的操作符&#xff1a; 操作符描述IN在指定的集合范围之内&#xff0c;多选一NOT IN不在指定的集合范围之内 案例&#xff1a;查询"教研部"和"…

【UE 材质】冰冻效果

效果 步骤 1. 打开“Quixel Bridge” 下载冰的纹理 2. 新建一个材质&#xff0c;这里命名为“M_Frozen” 打开“M_Frozen”&#xff0c;添加如下节点&#xff0c;此时我们可以通过控制参数“偏移”来改变边界的偏移 此时预览效果如下 如果增加参数“偏移”的默认值效果如下 3.…

Transformer中的自注意力机制计算过程分析

目录 1 什么是自注意力机制 2 自注意力的计算过程 1 什么是自注意力机制 自注意力机制&#xff08;Self-Attention&#xff09;顾名思义就是关注单个序列内部元素之间的相关性&#xff0c;不仅可以用于 seq2seq 的机器翻译模型&#xff0c;还能用于情感分析、内容提取等场景…

Doris实战——美联物业数仓

目录 一、背景 1.1 企业背景 1.2 面临的问题 二、早期架构 三、新数仓架构 3.1 技术选型 3.2 运行架构 3.2.1 数据模型 纵向分域 横向分层 数据同步策略 3.2.2 数据同步策略 增量策略 全量策略 四、应用实践 4.1 业务模型 4.2 具体应用 五、实践经验 5.1 数据…

Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径

一、前言 在Spring Boot项目开发过程中&#xff0c;对于接口API发布URL访问路径&#xff0c;一般都是在类上标识RestController或者Controller注解&#xff0c;然后在方法上标识RequestMapping相关注解&#xff0c;比如&#xff1a;PostMapping、GetMapping注解&#xff0c;通…

Java项目:30 基于SpringBoot自习室座位预定系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 功能设计 管理员 1、用户管理 管理员可以新增、删除管理员 管理员可以删除学生 2、自习室管理 管理员可以新增自习室、设置自习室的座位…

关于福彩历史数据采集器和体彩历史数据采集器的下载安装说明

前段时间因为研究基于人工神经网络&#xff08;深度学习&#xff0c;所谓的“AI”算法&#xff09;对3D开奖数据进行预测&#xff0c;开发了两款浏览器插件----“福彩历史数据采集器”和“体彩历史数据采集器”。之所以开发这两款插件&#xff0c;是因为不管是基于什么样的方式…

机器学习:集成学习(Python)

一、Adaboost算法 1.1 Adaboost分类算法 adaboost_discrete_c.py import numpy as np import copy from ch4.decision_tree_C import DecisionTreeClassifierclass AdaBoostClassifier:"""adaboost分类算法&#xff1a;既可以做二分类、也可以做多分类&#…

缓存相关问题:雪崩、穿透、预热、更新、降级的深度解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 1. 缓存雪崩 1.1 问题描述 1.2 解决方案 1.2.1 加锁防止并发重建缓存 2. 缓存穿透 2.1 问题描述 2.2 解决方案 2.2.1 …

Ubuntu下安装Scala

前言 弄了一下终于成功装上了&#xff0c;这里对此进行一下总结 安装虚拟机 VMware虚拟机安装Ubuntu&#xff08;超详细图文教程&#xff09;_vmware安装ubuntu-CSDN博客https://blog.csdn.net/qq_43374681/article/details/129248167Download Ubuntu Desktop | Download | …

FinalShell连接Linux

远程连接linux 我们使用VMware可以得到Linux虚拟机&#xff0c;但是在/Mware中操作Linux的命令行页面不太方便&#xff0c;主要是: 内容的复制、粘贴跨越VMware不方便 文件的上传、下载跨越VMware不方便 不方便也就是和Linux系统的各类交互&#xff0c;跨越VMwar 到Linux操作系…