Qt QWidget 简约美观的加载动画 第二季

😃 第二季来啦 😃
简约的加载动画,用于网络查询等耗时操作时给用户的提示.
这是最终效果:
在这里插入图片描述

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

//main.cpp
#include "LoadingAnimWidget.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QGridLayout>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;w.setWindowTitle("加载动画 第二季");QGridLayout * mainLayout = new QGridLayout;auto* anim1= new BouncingBalls;mainLayout->addWidget(anim1,0,0);auto* anim2 = new SlinkyCircle;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
public:LoadingAnimBase(QWidget* parent=nullptr);virtual ~LoadingAnimBase();
public slots:virtual void exec();virtual void start();virtual void stop();
protected:QPropertyAnimation mAnim;qreal mAngle;
};class BouncingBalls:public LoadingAnimBase//一蹦一蹦的小球
{Q_OBJECTQ_PROPERTY(qreal angle READ angle WRITE setAngle)
public:explicit BouncingBalls(QWidget* parent = nullptr);qreal angle()const;void setAngle(qreal an);
protected:void paintEvent(QPaintEvent *event);
};
class SlinkyCircle:public LoadingAnimBase{//可以伸缩的管子,绕着中心转动,就像弹簧圈,英语叫做slinky,查了好久才查到这个单词,有点强迫症😂Q_OBJECTQ_PROPERTY(qreal angle READ angle WRITE setAngle)
public:explicit SlinkyCircle(QWidget* parent = nullptr);qreal angle()const;void setAngle(qreal an);
protected:void paintEvent(QPaintEvent *event);
};#endif // LOADINGANIMWIDGET_H
//LoadingAnimWidget.cpp
#include "LoadingAnimWidget.h"
#include <QDebug>
#include <QPaintEvent>
#include <QPainter>
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();
}BouncingBalls::BouncingBalls(QWidget* parent):LoadingAnimBase (parent){
}
qreal BouncingBalls::angle()const{return mAngle;}
void BouncingBalls::setAngle(qreal an){mAngle = an;update();
}
void BouncingBalls::paintEvent(QPaintEvent *event){//这个动画和角度无关,但还是保留了之前的360度,因为360这个数字很好,除以谁都除的清QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setPen(Qt::NoPen);static const QStringList colorList{"yellow","orangered","lime","coral","steelblue"};const int x = width();const int y = height();const int d = 0.1*x;    //小球的直径static const int startAngle[5] = {0,45,90,135,180};//五个小球启动时间点static const qreal maxHeight = 0.25*y;//小球蹦起来的最大高度painter.translate(1.0/6 * x - d/2, 0.5 * y);//最左边的小球的静止坐标是 (1/6*x , 0.6*y),画圆的起点是左上角,所以x坐标还要减去半径for(int i = 0;i < 5;++i){const auto start = startAngle[i];qreal delta = mAngle - start;painter.setBrush(QBrush(QColor(colorList[i])));if(delta > 0 && delta < 180){//每个小球蹦起来的持续时间是4个单位,每个单位是45if(delta > 90) delta = 180 - delta;painter.drawEllipse(QRectF(0,-maxHeight * delta / 90.0,d,d));}else{//原地不动painter.drawEllipse(QRectF(0,0,d,d));}painter.translate(x/6.0,0);}
}
SlinkyCircle::SlinkyCircle(QWidget* parent):LoadingAnimBase (parent){mAnim.setEasingCurve(QEasingCurve::InOutCubic);
}
qreal SlinkyCircle::angle()const{ return mAngle;}
void SlinkyCircle::setAngle(qreal an){mAngle = an;update();
}void SlinkyCircle::paintEvent(QPaintEvent *event){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setPen(Qt::NoPen);//画一个番茄色的背景painter.setBrush(QBrush(QColor("tomato")));painter.drawRoundedRect(this->rect(),8,8);//画圆弧painter.setBrush(Qt::NoBrush);const int x = this->width();const int y = this->height();QPen pen("white");pen.setCapStyle(Qt::RoundCap);pen.setWidth(x/20);painter.setPen(pen);painter.translate(x/2,y/2);static const qreal spanAngle = 45;//mAngle<=45,要把弧线拉伸出来static const qreal shrinkAngle = 360-spanAngle;//mAngle==315时,要把弧线收缩起来auto arcRect = this->rect().adjusted(x/5,y/5,-x/5,-y/5);arcRect.translate(-x/2,-y/2);static const int direction = -1;//顺时针if(mAngle < spanAngle){painter.drawArc(arcRect,90 * 16,mAngle * 16 * direction);}else{//弧长是固定的//40 - 320 --> 320 , 280 --> 320if(mAngle > shrinkAngle){painter.drawArc(arcRect,90 * 16,-(360-mAngle)*16 * direction);}else{//我转动的角度是当前角度 - 拉伸门槛,因为有收尾的不动的时间段,占据了一段角度,所以要把转动的角度拉伸一些,//这个比例就是 (360-spanAngle) / (shrinkAngle - spanAngle)const auto delta = (mAngle - spanAngle) * (360-spanAngle) / (shrinkAngle - spanAngle);painter.rotate(-delta * direction);painter.drawArc(arcRect,90 * 16,spanAngle * 16 * direction);}}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Golang】Golang使用embed加载、打包静态资源文件

【Golang】Golang使用embed加载、打包静态资源文件 大家好 我是寸铁&#x1f44a; 总结了一篇Golang使用embed加载静态资源文件的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 事情是这样的&#xff1a;前不久&#xff0c;有同学问我,golang怎么把静态资源文件打包成一…

STM32单片机基本原理与应用(九)

SDIO/SD卡实验 实验内容 将SD卡插入实训平台并烧写程序&#xff0c;开机后TFTLCD屏幕上会显示是否成功初始化SD卡并显示SD卡容量。 电路原理图 实验原理 SD卡的通信方式有两种&#xff1a;SPI和SDIO。SD卡有五种寄存器&#xff0c;如下表 SD 卡的指令由 6 个字节组成&…

2024年2月20日v1.0.5更新·优雅草便民工具youyacao-tools

2024年2月20日v1.0.5更新优雅草便民工具youyacao-tools apk下载 https://fenfacun.youyacao.com/tools105.apk 介绍 优雅草便民工具是一款由成都市一颗优雅草科技有限公司打造的便民查询公益工具&#xff0c;2024年1月17日正式发布v1.0.0版本&#xff0c;本工具为了方便大众免…

pclpy OC-Tree “体素内的邻居搜索”、“K 最近邻搜索”和“半径内的邻居搜索”

pclpy OC-Tree “体素内的邻居搜索”、“K 最近邻搜索”和“半径内的邻居搜索” 一、算法原理1.介绍2.“体素内的邻居搜索”、“K 最近邻搜索”和“半径内的邻居搜索” 二、代码三、结果1.原点云2.体素内的邻居搜索3.K 最近邻搜索4.半径内的邻居搜索 四、相关数据 一、算法原理…

python实现线下缓存最优算法

对于现代计算机为了加快数据存储速度&#xff0c;一般会采用多级缓存的方法&#xff0c;以最简单的二级缓存来说&#xff0c;数据会存放在两个地方&#xff0c;一个地方就是存在内存当中&#xff0c;另一个存放的地方就是存放在硬盘当中&#xff0c;但是这两个地方数据读取的速…

面向面试的机器学习知识点(4)——分类模型

省流版&#xff1a; 本文介绍机器学习中的回归算法&#xff1a;逻辑回归、KNN、SVM、随机森林和XGBoost。作为机器学习的有监督学习方法&#xff0c;分类模型是最重要也是最常见的一类算法&#xff0c;在数据分析等岗位的笔试面试中都是常客&#xff0c;非常值得深入研究&…

【elasticsearch实战】知识库文件系统检索工具FSCrawler

需求背景 最近有一个需求需要建设一个知识库文档检索系统&#xff0c;这些知识库物料附件的文档居多&#xff0c;有较多文档格式如&#xff1a;PDF, Open Office, MS Office等&#xff0c;需要将这些格式的文件转化成文本格式&#xff0c;写入elasticsearch 的全文检索索引&am…

JAVA--反射机制

目录 1. 反射(Reflection)的概念 1.1 反射的出现背景 1.2 反射概述 1.3 Java反射机制研究及应用 1.4 反射相关的主要API 1.5 反射的优缺点 2. 理解Class类并获取Class实例 2.1 理解Class 2.1.1 理论上 2.1.2 内存结构上 2.2 获取Class类的实例(四种方法) 2.3 哪些类…

本地部署ChatGPT

发布一下我之前做的一个本地大模型部署,不需要API key,但要有自己的账号 利用Docker 的Pandora做本地ChatGPT模型部署 先下载安装Docker,设置好运行如下 会要求升级核心,cmd运行如下命令就OK 安装Pandora 再管理员cmd中输入如下命令拉取Pandora镜像 docker pull pengzhi…

Makefile静态库动态库的构建和链接之工程实用篇

静态库和动态库的构建和链接 现有C工程目录结构如下&#xff1a; add.h int add(int a, int b);add.cpp #include "add.h"int add(int a, int b) {return ab; }main.cpp #include <iostream> #include "add.h"int main() {std::cout << a…

openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法

文章目录 openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法概述笔记查看特性列表openssl3.2编译脚本 - 加入enable-crypto-mdebug看看有没有替代内存诊断的方法?main.cppmy_openSSL_lib.hmy_openSSL_lib.c备注备注END openssl3.2 - crypto-mdebug被弃用后, 内存泄…

TransformerEncoder影评测试

import os import keras import tensorflow as tf from keras import layers import numpy as np#加载数据 def load_data(data_dir):"""data_dir&#xff1a;train的目录或test的目录输出&#xff1a;X&#xff1a;评论的字符串列表y&#xff1a;标签列表&…