Qt 简约美观的动画 摆钟风格 第十季

2024-03-03 18:52

本文主要是介绍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 简约美观的动画 摆钟风格 第十季的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770559

相关文章

QT 中ListView和ListWidget有什么区别

ListView和ListWidget在Qt框架中都是用于显示列表数据的控件,但它们在使用方法和特性上存在一些明显的差异。以下是关于它们用法不一样的地方的详细分析: 数据管理方式: ListView:使用QAbstractItemModel数据模型来管理和显示列表数据。QAbstractItemModel是一个抽象类,允许开发者自定义数据模型以适应特定的数据结构和需求。这使得ListView在处

如何使用Qt的PIMPL习惯用法(PIMPL Idiom

) PIMPL是指“Pointer to IMPLementation”(指向实现的指针),意味着将实现细节隐藏起来,用户类无需关注这些实现细节。在Qt中常用PIMPL习惯用法来清晰地区分接口与实现,尽管Qt官方文档并未详细说明该机制。本文将演示如何在Qt中使用PIMPL习惯用法,并以一个简单的坐标输入对话框作为实例。 原理与动机 PIMPL的核心在于将类的实现细节封装在一个私有类中,这个私

【Qt6.3 基础教程 17】 Qt布局管理详解:创建直观和响应式UI界面

文章目录 前言布局管理的基础为什么需要布局管理器? 盒布局:水平和垂直排列小部件示例:创建水平盒布局 栅格布局:在网格中对齐小部件示例:创建栅格布局 表单布局:为表单创建标签和字段示例:创建表单布局 调整空间和伸缩性示例:增加弹性空间 总结 前言 当您开始使用Qt设计用户界面(UI)时,理解布局管理是至关重要的。布局管理不仅关系到UI的外观,更直接影响用户交互的体验。本篇博

【Qt6.3 基础教程 16】 掌握Qt中的时间和日期:QTimer和QDateTime的高效应用

文章目录 前言QTimer:定时任务的强大工具QTimer的基本用法高级特性:单次定时器 QDateTime:处理日期和时间获取当前日期和时间日期和时间的格式化输出日期和时间计算 用例:创建一个倒计时应用结论 前言 在开发桌面应用程序时,处理时间和日期是一个常见且重要的任务。Qt框架提供了强大的工具来处理与时间相关的功能,其中QTimer和QDateTime是最核心的类。本

ArkTS开发系列之导航 (2.7动画)

上篇回顾: ArkTS开发系列之导航 (2.6 图形) 本篇内容:动画的学习使用 一、 知识储备 1. 布局更新动画 包含显式动画(animateTo)和属性动画(animation) 动画类型名称特点显式动画闭包内的变化都会触发动画执行, 可以做较复杂的动画属性动画属性变化时触发动画执行, 设置简单 说白了,显示动画就是靠闭包事件触发,属性动画是挂在组件身上的属性变化触发 显式动画

基于ZYNQ7000的交叉编译工具链Qt+OpenCV+ffmpeg等库支持总结

最近刚刚接触XILINX的ZYNQ板,刚接触没有十天。XILINX定位它为SOC,我也很认同,起码比TI定位MPU为SOC强很多。据说今年TI的最新产品也加入了ZYNQ板。 之前的MIPS处理器设计与实现的项目就算做告一段落,搞了将近7个月,成果显著,收获颇多,最近打算搞搞ZYNQ。 之前MIPS也有一套交叉编译工具,不过是老师提供的,自己也尝试搞了搞,太辛苦了,而且也没什么成果,因为我

Qt 5.2.0 qwt-6.1.0

环境:win7(32) qt-5.2.0 qwt-6.1.0(qt-6.1.0说支持qt5以上的版本,但是我在配置前没找到最新的qt-5.2.0与qwt-6.1.0,其实步骤的差不多,暂时没发现版本引起的问题) 一.添加环境变量(在cmd测试下qmake,如果有问题重启电脑):  Add "C:\Qt\Qt5.0.1\5.0.1\mingw47_32\bin" to your systems

Android 扇形网络控件 - 无网络视图(动画)

前言 一般在APP没有网络的情况下,我们都会用一个无网络的提示图标,在提示方面为了统一app的情况,我们一般使用简单的提示图标,偶尔只需要改变一下图标的颜色就一举两得,而不需要让PS来换一次颜色。当然app有图标特殊要求的就另当别论了。 效果图 当你第一眼看到这样的图,二话不说直接让UI给你切一张图标来的快对吧,我其实开始也是这么想的,但是到了做的app越来越多的时候,你就会发现就算是用

防止在 Qt 中触发信号

在 Qt 中工作时,有时我们需要暂时阻止某些信号的触发。以下是一个经典场景:我们有一个 QCheckBox 对象,当用户勾选或取消勾选时,需要调用一个函数,因此我们将这个函数连接到 stateChanged(int state) 信号。然而,在某些条件下,我们在代码中更改 QCheckBox 的状态,这会导致触发不需要的信号。那么如何在特定情况下防止信号触发呢? 使用 clicked 信号 如