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

news2024/11/15 12:38:23

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

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

//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.coloradmin.cn/o/1484278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

扼杀网络中的环路:STP、RSTP、MSTP

目录 前言&#xff1a; 一、STP&#xff08;Spanning Tree Protocol&#xff09; 1.1 STP功能 1.2 STP应用 二、RSTP&#xff08;Rapid Spanning Tree Protocol&#xff09; 2.1 RSTP功能 2.2 RSTP应用 三、MSTP&#xff08;Multiple Spanning Tree Protocol&#xff0…

Filebeat将csv导入es尝试

一、安装 在docker中安装部署ELKfilebeat 二、主要配置 - type: log # Change to true to enable this input configuration. enabled: true # Paths that should be crawled and fetched. Glob based paths. paths: - /home/centos/pip_v2.csv #源路径 #…

了解Spring中Bean:配置与作用域

作为一名对技术充满热情的学习者&#xff0c;我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代&#xff0c;我远非专家&#xff0c;而是一位不断追求进步的旅行者。通过这篇博客&#xff0c;我想分享我在某个领域的学习经验&#xff0c;与大家共同探讨、共…

几种常见的自动化测试框架

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在软件测试领域&#xff0c;自动化测试框架有很多&#xff0c;这里主要介绍几种常用的自动化测试…

程序员必备开发工具

Chat GPT的升级节奏让人们越来越惊讶的同时,也让大家感觉到了压力,在如此快节奏的互联网世界中,开发人员需要不断学习与更新知识,保持领先地位并高效地交付高质量软件。 无论是集成开发环境 (IDE)、版本控制系统、测试工具、协作平台还是文档工具,学习并掌握这些流行的顶…

嵌入式学习31-指针和函数知识回顾

1.指针&#xff1a; 1.提供一种间接访问数据的方法 2.空间没有名字,只有一个地址编号 2.指针: 1.地址:区分不同内存空间的编号 2.指针:指针就是地址,地址就是指针 3.指针变量:存放指针的变量称为指针变量,简称为指针 3.指针的定义: int *p NULL; …

mysql order by布尔盲注

什么是order by 在MySQL支持使用ORDER BY语句对查询结果集进行排序处理&#xff0c;使用ORDER BY语句不仅支持对单列数据的排序&#xff0c;还支持对数据表中多列数据的排序。语法格式如下 select * from 表名 order by 列名(或者数字) asc&#xff1b;升序(默认升序) selec…

Spark(1)-wordCount入门

1. 创建Maven项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

【DDD】学习笔记-实体和值对象:从领域模型的基础单元看系统设计

今天我们来学习 DDD 战术设计中的两个重要概念&#xff1a;实体和值对象。 这两个概念都是领域模型中的领域对象。它们在领域模型中起什么作用&#xff0c;战术设计时如何将它们映射到代码和数据模型中去&#xff1f;就是我们这一讲重点要关注的问题。 另外&#xff0c;在战略…

每日五道java面试题之mysql数据库篇(二)

目录&#xff1a; 第一题. 什么是索引&#xff1f;第二题. 索引有哪些优缺点&#xff1f;第三题. 创建索引的原则第四题. 创建索引时需要注意什么&#xff1f;第五题. 使用索引查询一定能提高查询的性能吗&#xff1f;为什么&#xff1f; 第一题. 什么是索引&#xff1f; 索引…

【前端素材】推荐优质后台管理系统网页my-Task平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使用。后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功…

查找算法——java

顺序查找&#xff08;顺序表查找&#xff09; 顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线形表的一端开始&#xff0c;顺序扫描&#xff0c;依次将扫描到的结 点关键字与给定值k相比较&#xff0c;若相等则表示查找成功&#xff1b;若扫描结束仍没…

web服务器nginx下载及在win11的安装

一.背景 还是为了公司安排的师带徒任务。 操作系统版本&#xff1a;win11 家庭版 mginx版本&#xff1a;1.24.0 二.nginx版本选择与下载 我之前也写过下载nginx下载_ngnix stable 下载-CSDN博客 不想看寻找过程的&#xff0c;直接点这里去下载https://nginx.org/download…

抖音视频评论抓取软件|视频批量下载

抖音视频评论采集软件是一款基于C#开发的高效、便捷的工具&#xff0c;旨在为用户提供全面的数据采集和分析服务。该软件不仅支持通过关键词进行搜索抓取&#xff0c;还能够通过分享链接进行单个视频的抓取和下载&#xff0c;让用户轻松获取抖音视频评论数据。 &#x1f50d; …

记录西门子:SCL博图

算术表达式: 关系表达式&#xff1a; 逻辑表达式&#xff1a; 赋值运算

云时代【6】—— 镜像 与 容器

云时代【6】—— 镜像 与 容器 四、Docker&#xff08;三&#xff09;镜像 与 容器1. 镜像&#xff08;1&#xff09;定义&#xff08;2&#xff09;相关指令&#xff08;3&#xff09;实战演习镜像容器基本操作离线迁移镜像镜像的压缩与共享 2. 容器&#xff08;1&#xff09;…

MSCKF3讲:后端理论推导(上)

MSCKF3讲&#xff1a;后端理论推导&#xff08;上&#xff09; 文章目录 MSCKF3讲&#xff1a;后端理论推导&#xff08;上&#xff09;1 MSCKF中的状态变量① IMU状态:② cam0状态&#xff1a;③ IMU和cam0间状态关系 2 微分方程递推&#xff08;数值解&#xff09;3 IMU状态预…

洛谷C++简单题小练习day22—小鱼记忆小程序!一题五解,高效学习

day22--小鱼记忆--2.26 习题概述 题目描述 小鱼最近被要求参加一个数字游戏&#xff0c;要求它把看到的一串数字 ai​&#xff08;长度不一定&#xff0c;以 0 结束&#xff09;&#xff0c;记住了然后反着念出来&#xff08;表示结束的数字 0 就不要念出来了&#xff09;。…

【高级数据结构】Trie树

原理 介绍 高效地存储和查询字符串的数据结构。所以其重点在于&#xff1a;存储、查询两个操作。 存储操作 示例和图片来自&#xff1a;https://blog.csdn.net/qq_42024195/article/details/88364485 假设有这么几个字符串&#xff1a;b&#xff0c;abc&#xff0c;abd&…

数字中国:构建智慧社会的未来蓝图

一、引言 随着信息技术的迅猛发展&#xff0c;数字中国已经成为推动社会进步、提升国家竞争力的重要引擎。数字中国不仅代表着信息技术的广泛应用&#xff0c;更代表着一种全新的社会形态和发展模式。在这个背景下&#xff0c;AI与大数据技术的融合与应用成为数字中国建设的核…