Qt QWidget 简约美观的加载动画 第五季 - 小方块风格

news2024/9/29 11:28:34

给大家分享两个小方块风格的加载动画
😊 第五季来啦 😊 效果如下:
在这里插入图片描述

一个三个文件,可以直接编译运行

//main.cpp
#include "LoadingAnimWidget.h"
#include <QApplication>
#include <QGridLayout>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget w;
    w.setWindowTitle("加载动画 第5季");
    QGridLayout * mainLayout = new QGridLayout;

    auto* anim1= new RhombusShift;
    mainLayout->addWidget(anim1,0,0);

    auto* anim2 = new TiltingBricks;
    mainLayout->addWidget(anim2,0,1);

    w.setLayout(mainLayout);
    w.show();
    anim1->start();
    anim2->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 RhombusShift:public LoadingAnimBase{//做斜向平移的四个菱形
public:
    explicit RhombusShift(QWidget* parent = nullptr);
protected:
    void paintEvent(QPaintEvent*);
};
class TiltingBricks:public LoadingAnimBase{//三个正方形一个接一个倾斜倒向右侧
public:
    explicit TiltingBricks(QWidget* parent = nullptr);
protected:
    void paintEvent(QPaintEvent*);
};

#endif // LOADINGANIMWIDGET_H

//LoadingAnimWidget.cpp
#include "LoadingAnimWidget.h"
#include <QDebug>
#include <QPaintEvent>
#include <QPainter>
#include <QtMath>
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();
}

RhombusShift::RhombusShift(QWidget* parent):LoadingAnimBase (parent){
    mAnim.setDuration(4800);
}
void RhombusShift::paintEvent(QPaintEvent*){
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    const int x = width();
    const int y = height();
    static const int cornerGap = 4;//菱形内部顶点和中心点的距离
    static const int edgeGap = 2;//菱形顶点和外边框的距离
    const qreal edgeLen = (x/2 - cornerGap - edgeGap) / 1.42;// 菱形的边长
    const int halfDiagonalx = (x/2 - edgeGap - cornerGap )/2;//水平方向一半对角线长度
    const int halfDiagonaly = (y/2 - edgeGap - cornerGap )/2;//垂直方向一半对角线长度
    const QPointF point1(x/2,edgeGap + halfDiagonaly);          //上方
    const QPointF point2(x/2 + cornerGap + halfDiagonalx , y/2);//右侧
    const QPointF point3(x/2, y/2 + cornerGap + halfDiagonaly); //下方
    const QPointF point4(edgeGap + halfDiagonalx,y/2);          //左侧
    const QList<QPointF> pointList{point1,point2,point3,point4,point1,point2,point3,point4};

    QPainterPath pathList[4];
    for(int i = 0;i < 4; ++i){
        auto & path = pathList[i];
        path.moveTo(pointList[i]);
        path.lineTo(pointList[i+1]);
        path.lineTo(pointList[i+2]);
        path.lineTo(pointList[i+3]);
        path.lineTo(pointList[i+4]);
    }
    static const QColor brushList[4] = {"lightblue" , "cadetblue" , "lightblue" , "cadetblue"};
    static const int staticTime = 15;//每次移动到四个节点上面,要静止一段时间,这个值在0-90之间
    for(int i = 0;i < 4;++i){
        qreal proportion = 0;
        const auto rest = fmod(mAngle,90);//余数
        const auto quotient = (int)mAngle / 90 * 0.25;//商
        if(rest > 90 - staticTime) proportion = quotient + 0.25;
        else proportion = rest / (90 - staticTime) * 0.25 + quotient;
        const QPointF center = pathList[i].pointAtPercent(proportion);
        painter.translate(center);
        painter.rotate(45);
        painter.setBrush(QBrush(brushList[i]));
        painter.drawRect(-edgeLen/2,-edgeLen/2,edgeLen,edgeLen);
        painter.resetTransform();
    }
}
TiltingBricks::TiltingBricks(QWidget* parent):LoadingAnimBase (parent){
    mAnim.setDuration(4000);
}
void TiltingBricks::paintEvent(QPaintEvent*){
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);

    static const QColor brushList[3] = {"lightcoral" , "lightblue" , "khaki"};

    const int x = width();
    const int y = height();
    painter.translate(x/2,y/2);

    const int edgeGap = 4;
    const int cornerGap = 2;

    const int edgeLen = x/3 - edgeGap - cornerGap;
    const QRectF point1(-edgeLen-cornerGap,-edgeLen-cornerGap,edgeLen,edgeLen);//左上
    const QRectF point2(-edgeLen-cornerGap,cornerGap,edgeLen,edgeLen);//左下
    const QRectF point3(cornerGap,cornerGap,edgeLen,edgeLen);//右下
    const QRectF point4(cornerGap,-cornerGap-edgeLen,edgeLen,edgeLen);//右上

    const QList<QRectF> baseRectList{point1,point2,point3};
    qreal ang = mAngle;
    int round = (int)ang / 90;
    if(round >= 4) round = 0;
    ang = fmod(ang,90);
    const int rectIdx = (int)ang / 30;
    ang = fmod(ang,30) * 3;

    painter.rotate(90*round);
    for(int i = 0;i < 3;++i){
        painter.setBrush(QBrush(brushList[i]));
        if(i == rectIdx){
            painter.rotate(ang);
            painter.drawRoundedRect(baseRectList[i],4,4);
            painter.rotate(-ang);
        }
        else{
            if(i < rectIdx){
                painter.rotate(90);
                painter.drawRoundedRect(baseRectList[i],4,4);
                painter.rotate(-90);
            }
            else{
                painter.drawRoundedRect(baseRectList[i],4,4);
            }
        }
    }
}


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

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

相关文章

时间序列分析实战(四):Holt-Winters建模及预测

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

C++ //练习 9.24 编写程序,分别使用at、下标运算符、front和begin提取一个vector中的第一个元素。在一个空vector上测是你的程序。

C Primer&#xff08;第5版&#xff09; 练习 9.24 练习 9.24 编写程序&#xff0c;分别使用at、下标运算符、front和begin提取一个vector中的第一个元素。在一个空vector上测是你的程序。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;v…

详解POCV/SOCV的时序报告

​POCV/SOCV的时序报告中有如下变量&#xff1a; Mean: 高斯分布中的μ值&#xff08;平均值&#xff09; Sensit: sensitivity&#xff0c;也就是1个Sigma的值&#xff1b; Corner: Sigma边界的最差值 cell的delay Delay mean N * Delay sigma; cell 的Transition Sl…

UE5 C++ Widget练习 Button 和 ProgressBar创建血条

一. 1.C创建一个继承Widget类的子类&#xff0c; 命名为MyUserWidget 2.加上Button 和 UserWidget的头文件 #include "CoreMinimal.h" #include "Components/Button.h" #include "Blueprint/UserWidget.h" #include "MyUserWidget.genera…

OpenCV 16 - Qt使用opencv视觉库

1 下载好opencv视觉库 不知道怎么下载和编译opencv视觉库的可以直接使用这个 : opencvcv_3.4.2_qt 2 解压opencv包 3 打开opencv的安装目录 4.打开x86/bin 复制里面所有的dll文件&#xff0c;黏贴到C/windows/syswow64里面 5 新建Qt项目 6 修改pro文件:添加对应的头文件和库文件…

【HMAC-SHA1算法以及工作原理】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱总结 简述概要 连接HMAC-SHA1工作原理以及工具代码 知识图谱 HMAC&#xff08;Hash-based Message Authentication Code&#xff0c;基于散列的消息认证码&#xff09;是一种结合了密钥和消息的认证方法…

Python算法题集_全排列

Python算法题集_全排列 题46&#xff1a;全排列1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【标记数组递归】2) 改进版一【指针递归】3) 改进版二【高效迭代模块】4) 改进版三【高效迭代模块极简代码】 4. 最优算法5. 相关资源 本文为Python…

【GPTs分享】每日GPTs分享之Image Generator Tool

今日GPTs分享&#xff1a;Image Generator Tool。Image Generator Tool是一种基于人工智能的创意辅助工具&#xff0c;专门设计用于根据文字描述生成图像。这款工具结合了专业性与友好性&#xff0c;鼓励用户发挥创造力&#xff0c;同时提供高效且富有成效的交互体验。 主要功能…

【新书推荐】8.1 数组

第八章 数组 数组是程序设计中最常用的数据类型之一。数组表示在指定的内存地址处&#xff0c;连续存储具有相同数据类型的一组元素。每个数组元素可以视为一个单独的变量&#xff0c;使用数组名和数组下标来表示。例如int类型的数组元素a[2]&#xff0c;表示在内存地址a处&am…

input输入框过滤非金额内容保留一个小数点和2位小数

这篇是输入框过滤非金额内容保留一个小数点和2位小数&#xff0c;金额的其他格式化可以看这篇文章常用的金额数字的格式化方法 js方法直接使用 该方式可以直接使用过滤内容&#xff0c;也可以到onInput或onblur等地方过滤&#xff0c;自行使用 /*** 非金额字符格式化处理* p…

Java数据结构---初识集合框架

目录 一、什么是集合框架 二、集合框架的重要性 三、背后涉及的数据结构及算法 1.什么是数据结构 2.容器背后对应的数据结构 3.相关的Java知识 4.什么是算法 一、什么是集合框架 Java 集合框架 Java Collection Framework &#xff0c;又被称为容器 container &#xff0…

深度学习基础(三)循环神经网络(RNN)

之前的章节我们初步介绍了卷积神经网络&#xff08;CNN&#xff09;&#xff1a; 深度学习基础&#xff08;二&#xff09;卷积神经网络&#xff08;CNN&#xff09;-CSDN博客文章浏览阅读2次。卷积神经网络&#xff08;CNN&#xff09;的应用领域广泛&#xff0c;尤其在图像处…

设计模式(八)外观模式

相关文章设计模式系列 1.外观模式简介 外观模式介绍 当我们开发Android的时候&#xff0c;无论是做SDK还是封装API&#xff0c;我们大多都会用到外观模式&#xff0c;它通过一个外观类使得整个系统的结构只有一个统一的高层接口&#xff0c;这样能降低用户的使用成本。 外观…

片上网络NoC

本文大部分内容来源于王志英老师主编的《片上网络原理与设计》以及网络&#xff0c;部分内容是本人理解所得&#xff0c;若有不当之处请指教 一、概述 片上网络将报文交换的思想引入芯片内部通信机制中&#xff0c;尽管片上网络和片外网络具有一定相似性&#xff0c;但二者在…

Vue 实现页面导出A4标准大小的PDF文件,以及处理图片跨域不能正常展示的问题等

效果预览&#xff1a; 代码流程&#xff1a;首先在utils文件夹下创建htmlToPdf的js工具文件&#xff0c;然后在main.js中注册引用 htmlToPdf.js // 导出页面为PDF格式 import html2Canvas from html2canvas import JsPDF from jspdfexport default {install(Vue, options) {V…

el-table样式问题:如何修改element-ui表格中按钮悬浮显示但是被el-table溢出隐藏的问题?

最近在写elment-ui样式表格中遇到了溢出隐藏的问题 修改前 修改后 是由于el-table__body-wrapper为 overflow&#xff1a;hidden导致的 解决方式&#xff1a; .el-table__body-wrapper {overflow: visible !important; } //或者 /deep/.el-table__body-wrapper {overflow: v…

更换个人开发环境后,pycharm连接服务器报错Authentication failed

原因&#xff1a;服务器中更换个人开发环境后&#xff0c;密码变了。 解决&#xff1a;在pycharm中修改服务器开发环境密码即可。 1 找到Tools-Depolyment-Configuration 2 点击SSH Configuration后的省略号 3 修改这里面的Password即可

刷题日记 | 字符串扩容和增强型for循环

for(char c:s)遍历字符串 增强型for循环 C for(char c:s)遍历字符串 增强型for循环_c for (char c : s)-CSDN博客 字符串使用前要进行扩容 reserve函数 【CString类成员函数辨析】resize(),size(),capacity(),reserve()函数的解析与对比_c reserve函数-CSDN博客 a.size() 用来…

鲲鹏arm64架构下安装KubeSphere

鲲鹏arm64架构下安装KubeSphere 官方参考文档: https://kubesphere.io/zh/docs/quick-start/minimal-kubesphere-on-k8s/ 在Kubernetes基础上最小化安装 KubeSphere 前提条件 官方参考文档: https://kubesphere.io/zh/docs/installing-on-kubernetes/introduction/prerequi…

SIMON 32/64加密电路的实现(System Verilog)

关于SIMON加密电路的原理&#xff0c;参考之前发布的博文【SIMON加密算法的原理】 1.总览与电路介绍 1.1 电路总体结构图 1.2 模式配置介绍 SIMON加密算法的分组长度、密钥长度以及必要的参数配置如下图&#xff1a; 本次需要实现的是SIMON 32/64&#xff0c;即分组长度2n3…