Qt 简约美观的动画 摆钟风格 第十季
😊 今天给大家分享一个摆钟风格的加载动画 😊
效果如下:
最近工作忙起来了 , 后续再分享其他有趣的加载动画吧.
一共三个文件 , 可以直接编译运行
//main.cpp
#include "LoadingAnimWidget.h"
#include <QApplication>
#include <QGridLayout>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;w.setWindowTitle("加载动画 第10季");QGridLayout * mainLayout = new QGridLayout;auto* anim1 = new ThreeMovingZoomingBalls;mainLayout->addWidget(anim1,0,0);auto* anim2 = new FourRotatingFireBall;mainLayout->addWidget(anim2,0,1);auto* anim3 = new CookieMonster;mainLayout->addWidget(anim3,0,2);auto* anim4 = new StickCircle;anim4->setStickColor("lime");anim4->setStickWidth(16);anim4->setStickLength(32);mainLayout->addWidget(anim4,1,0);auto* anim5 = new PendulumClock;mainLayout->addWidget(anim5,1,1);auto* anim6 = new AmpereMeter;mainLayout->addWidget(anim6,1,2);w.setLayout(mainLayout);w.show();anim1->start();anim2->start();anim3->start();anim4->start();anim5->start();anim6->start();return a.exec();
}
//LoadingAnimWidget.h
#ifndef LOADINGANIMWIDGET_H
#define LOADINGANIMWIDGET_H
#include <QPropertyAnimation>
#include <QWidget>
class LoadingAnimBase:public QWidget
{Q_OBJECTQ_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 StickCircle:public LoadingAnimBase
{Q_OBJECT
public:explicit StickCircle(QWidget* parent = nullptr);void setStickLength(qreal len);void setStickWidth(qreal len);void setStickColor(const QColor& color);
protected:void paintEvent(QPaintEvent *event);
private:qreal mStickLen;qreal mStickWidth;QColor mStickColor;
};
class ThreeMovingZoomingBalls:public LoadingAnimBase{//三个一边移动一边缩放的小球
public:ThreeMovingZoomingBalls(QWidget* parent = nullptr);
protected:void paintEvent(QPaintEvent*);
};
class FourRotatingFireBall:public LoadingAnimBase{//四个旋转的火球,说他是火球是因为快速转动的时候它有残影,看上去像弧线
public:FourRotatingFireBall(QWidget* parent = nullptr);
protected:void paintEvent(QPaintEvent*);
};
class CookieMonster:public LoadingAnimBase{//一个不停吃饼干的怪兽
public:CookieMonster(QWidget* parent = nullptr);
protected:void paintEvent(QPaintEvent*);
};
class PendulumClock:public LoadingAnimBase{//吊钟钟摆
public:PendulumClock(QWidget* parent = nullptr);
protected:void paintEvent(QPaintEvent*);
};
class AmpereMeter :public LoadingAnimBase{//电流表的指针
public:AmpereMeter(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 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();
}
qreal LoadingAnimBase::angle()const{ return mAngle;}
void LoadingAnimBase::setAngle(qreal an){mAngle = an;update();
}
StickCircle::StickCircle(QWidget *parent) : LoadingAnimBase(parent),mStickLen(-1),mStickWidth(10),mStickColor("black"){}
void StickCircle::setStickLength(qreal len){if(len > 0 && len != mStickLen){mStickLen = len;update();}
}
void StickCircle::setStickWidth(qreal len){if(len > 0 && len != mStickWidth){mStickWidth = len;update();}
}
void StickCircle::setStickColor(const QColor& color){if(color.isValid() && mStickColor != color){mStickColor = color;update();}
}
void StickCircle::paintEvent(QPaintEvent *event){QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing);int x = width();int y = height();qreal ang = mAngle;painter.setPen(Qt::NoPen);painter.translate(x/2,y/2);QColor lightColor = mStickColor;lightColor.setAlphaF(0.1);const int stickw = mStickWidth;//小棍子的宽度qreal stickl = x / 4;//小棍子的长度if(mStickLen > 0) stickl = mStickLen;QColor highlight = mStickColor;const int startIdx = ang / 30;//开头的深色小棍子的索引号const int arr[14] = {0,1,2,3,4,5,6,7,8,9,10,11,0,1};QList<int> hightlightList{arr[startIdx],arr[startIdx+1],arr[startIdx+2]};QList<qreal> alphaList{0.5,0.75,0.99};//三根深色的小棍子的透明度for(int i = 0;i < 12;++i){if(hightlightList.contains(i)){auto hc = highlight;hc.setAlphaF(alphaList[0]);painter.setBrush(QBrush(hc));alphaList.pop_front();}else {painter.setBrush(QBrush(lightColor));}painter.drawRoundedRect(QRectF(-stickw/2,0.375*y -stickl/2-1,stickw,stickl),stickw/2,stickw/2);auto transform = painter.transform();transform.rotate(30);painter.setTransform(transform);}
}
ThreeMovingZoomingBalls::ThreeMovingZoomingBalls(QWidget* parent):LoadingAnimBase(parent){}
void ThreeMovingZoomingBalls::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setPen(Qt::NoPen);painter.setBrush(QBrush("cadetblue"));qreal x = width();qreal y = height();painter.translate(0,y/2);const qreal delta = 0.08*x;const qreal minr = 0.02*x;for(int i = 0;i < 5;++i){qreal ang = mAngle + 90*i;qreal posx = ang/360*x;if(posx > x) posx -= x;qreal r = minr + delta * qSin(M_PI / x * posx);painter.drawEllipse(QPointF(posx,0),r,r);}
}
FourRotatingFireBall::FourRotatingFireBall(QWidget* parent){}
void FourRotatingFireBall::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);QPen pen;pen.setCapStyle(Qt::RoundCap);pen.setWidth(12);painter.setPen(pen);painter.setBrush(Qt::NoBrush);const qreal x = width();const qreal y = height();const qreal r = 0.4*y;const qreal maxArc = 30;for(int i = 0;i <4;++i){painter.resetTransform();painter.translate(x/2,y/2);painter.rotate(90*i);if(i % 2 == 0){pen.setColor("lightblue");painter.setPen(pen);}else{pen.setColor("lightpink");painter.setPen(pen);}if(mAngle < 30){ //启动火球,画出弧线qreal ratio = mAngle / 30;painter.drawArc(QRectF(-r,-r,2*r,2*r),16*90,16*-ratio*maxArc);}else if(mAngle < 330){//转动两圈qreal ratio = (mAngle - 30) / 300;painter.rotate((720-maxArc)*ratio);painter.drawArc(QRectF(-r,-r,2*r,2*r),16*90,16*-maxArc);}else{//收起弧线qreal ratio = (mAngle - 330) / 30;painter.drawArc(QRectF(-r,-r,2*r,2*r),16*90,16*(1-ratio)*maxArc);}}
}
CookieMonster::CookieMonster(QWidget* parent):LoadingAnimBase(parent){}void CookieMonster::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);const qreal x = width();const qreal y = height();const qreal r = 0.2*x;painter.setPen(Qt::NoPen);painter.setBrush(QBrush("royalblue"));painter.translate(4,y/2);qreal startAngle = 22.5 + 22.5*qSin(M_PI / 90 * mAngle + M_PI/2);qreal span = 360 - 2*startAngle;painter.drawPie(QRectF(0,-r,2*r,2*r),startAngle*16,span*16);painter.setBrush(QBrush("white"));painter.drawEllipse(QPointF(r*0.8,-r/2),4,4);//画移动的小饼干painter.setBrush(QBrush("lightgreen"));painter.resetTransform();painter.translate(x,y/2);qreal ratio = mAngle / 360;for(int i = 0;i <3;++i){ratio += 0.333;if(ratio > 1) ratio -= 1;painter.drawEllipse(QPointF( -(x-2*r)*ratio,0 ) , 8,8);}
}
PendulumClock::PendulumClock(QWidget* parent):LoadingAnimBase(parent){}void PendulumClock::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);const qreal x = width();const qreal y = height();painter.translate(x/2,y/8);QPen pen("silver");pen.setWidth(4);painter.setPen(pen);painter.rotate(30*qSin(M_PI/180*mAngle));painter.setBrush(QBrush("silver"));painter.drawLine(0,0,0,0.6*y);painter.translate(0,0.6*y);painter.drawEllipse(QPointF(0,0),16,16);
}
AmpereMeter::AmpereMeter(QWidget* parent):LoadingAnimBase(parent){}void AmpereMeter::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);const qreal x = width();const qreal y = height();painter.translate(x/2,y*0.6);QPen pen("dimgray");pen.setWidth(4);painter.setPen(pen);painter.setBrush(Qt::NoBrush);const qreal r = x*0.4;//step1 先画一个表框painter.drawArc(QRectF(-r,-r,2*r,2*r),0,180*16);//step2 再画半圈刻度qreal gap = 180 / 14.0;painter.rotate(-90);for(int i = 1;i <= 13;++i){painter.rotate(gap);painter.drawLine(0,-r + 6,0,-r + 8);}//step3 画指针painter.resetTransform();painter.translate(x/2,y*0.6);painter.rotate(80*qSin(M_PI/180*mAngle));painter.drawLine(0,0,0,-r*0.7);}
相关文章:

Qt 简约美观的动画 摆钟风格 第十季
😊 今天给大家分享一个摆钟风格的加载动画 😊 效果如下: 最近工作忙起来了 , 后续再分享其他有趣的加载动画吧. 一共三个文件 , 可以直接编译运行 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <Q…...
Vue 3 中的 Composition API 详解
Vue.js,作为前端领域流行的框架之一,以其响应式数据绑定和组件化开发赢得了广大开发者的喜爱。随着前端技术的不断发展和项目复杂度的增加,Vue 团队推出了 Vue 3,并引入了 Composition API,以更好地满足复杂应用的需求…...

利用Python爬取高德地图全国地铁站点信息
利用Python中的requests库进行地铁站点信息的获取,同时将数据保存在本机excel中 # 首先引入所需要的包 import requests from bs4 import BeautifulSoup import pandas as pd import json# 发送 GET 请求获取网页内容 url http://map.amap.com/subway/index.html response r…...
Vue 3 中的 Teleport 特性详解
引言 在 Vue 3 中,引入了一个名为 Teleport 的新特性。这个特性允许开发者将组件的子组件“传送”到 DOM 中的任意位置,而不仅仅是它们的直接父级内部。这一功能在处理如模态框、弹出菜单、提示框等需要从其原始位置在视觉上移动到其他地方的用户界面元…...
小白的matlab简单应用
基本概念 1、数组array 数组是一个更通用的数据结构,可以是一维、二维或多维的。 一维数组通常被称为向量。 二维数组可以被视为矩阵。 多维数组可以用来表示更高维度的数据,例如三维数组可以表示一系列的矩阵。 用过的函数 20240229 1、读取excel文件…...

边缘计算网关在机床生产中的应用-天拓四方
随着工业4.0的推进,物联网(IoT)技术在各个工业领域中的应用日益广泛。特别是在机床行业,物联网技术的引入不仅提高了生产效率,还实现了对机床设备的实时监控和远程维护。在这一背景下,边缘计算网关的角色愈…...

maven配置文件(一)Settings配置
一、仓库 1、关系 我们依赖的外部服务是需要有地方进行存储的,而存储的地方就称之为仓库。其中仓库又分为本地仓库、中央仓库、镜像仓库、私服。 (1)本地仓库 当项目在本地编译或运行时,直接加载本地的依赖服务无疑是最快的。默…...

选择何种操作系统作为网站服务器
选择操作系统时,需考虑稳定性、安全性、成本、兼容性和技术支持等因素,常见选项有Windows Server和Linux发行版。 选择网站服务器的操作系统是一个关键的决策,因为它将影响到网站的性能、稳定性、安全性以及未来的扩展性,目前市场…...

【LeetCode】升级打怪之路 Day 11:栈的应用、单调栈
今日题目: Problem 1: 栈的应用 155. 最小栈 | LeetCode20. 有效的括号 | LeetCode150. 逆波兰表达式求值 | LeetCode Problem 2: 单调栈 496. 下一个更大元素 I739. 每日温度503. 下一个更大元素 II 目录 Problem 1:栈 - “先进后出”的应用LC 155. 最…...
题目 1454: 蓝桥杯历届试题-蚂蚁感冒
题目描述: 长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。 这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁…...

WP外贸营销型网站模板
WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题,适合时尚服装行业搭建wordpress企业官网使用。 零件配件WordPress外贸建站模板 汽车行业零配件WordPress外贸建站模板,卖配件、零件的外贸公司可以使用的WordPress主题。 https://www.jia…...
Linux获取进程(系统启动时间和运行时间)运行时间
Linux获取进程运行时间 思路:使用 ps - o命令 ps -p 986 -o etime可以获取进程986的执行时间,不论系统时间有没有发生改变,它都可以返回正确的结果: 总结:etime 是真正的程序运行时间,而不是系统运行时间与进程启动…...
服务器内部错误的原因
服务器内部错误的原因 软件问题。服务器上运行的软件可能存在程序错误、内存泄漏、配置错误等,这些错误可能导致服务器崩溃、服务无法正常运行或响应时间过长 硬件故障。服务器的硬件组件(如处理器、内存、硬盘等)可能会因故障或损坏而无法正…...

不愧是华为的,太厉害了。。。
🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号【互联网杂货铺】,回复 1 ,免费获取软件测试全套资料,资料在手,涨薪更快 实习去了博彦科技(外包),做的…...

贪心算法(区间问题)
452. 用最少数量的箭引爆气球 题目(求无重复区间) 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着…...
【Javascript】设计模式之策略模式
文章目录 1、使用策略模式计算奖金2、JavaScript 版本的策略模式3、应用:表单验证3.1 用策略模式进行表单验证3.2 给某个文本输入框添加多种校验规则 4、策略模式的优缺点 策略模式的定义是:定义一系列的算法,把它们一个个封装起来࿰…...
vue面试题:如何保存页面的当前的状态?
如何保存页面的当前的状态? 既然是要保持页面的状态(其实也就是组件的状态),那么会出现以下两种情况:组件会被卸载:(1)将状态存储在LocalStorage / SessionStorage优点:缺…...
Java的编程之旅34——Interger包装类
1.API简介 Java的API(Application Programming Interface,应用程序编程接口)是一组提供给程序员使用的代码库,用于开发Java应用程序。Java的API包括了各种类和接口,用于处理输入输出、图形用户界面、网络通信、数据库…...

C# Winform画图绘制圆形
一、因为绘制的圆形灯需要根据不同的状态切换颜色,所以就将圆形灯创建为用户控件 二、圆形灯用户控件 1、创建用户控件UCLight 2、设值用户控件大小(30,30)。放一个label标签,AutoSize为false(不自动调整大小),Dock为Fill(填充),textaglign为居中显示。 private Color R…...

Unity(第十六部)声音和视频
声音 1、听声音 创建相机的时候,相机自带Audio Listener 多个相机的时候,我们只保留一个Audio Listener就可以 2、声音源,环境音 添加Audio Source就行中文叫声音源 3、脚本执行的声音 using System.Collections; using System.Collection…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...