Qt+QWidget實(shí)現(xiàn)簡約美觀的加載動(dòng)畫
給大家分享兩個(gè)小方塊風(fēng)格的加載動(dòng)畫
第五季來啦
效果如下:

一個(gè)三個(gè)文件,可以直接編譯運(yùn)行
//main.cpp
#include "LoadingAnimWidget.h"
#include <QApplication>
#include <QGridLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.setWindowTitle("加載動(dòng)畫 第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{//做斜向平移的四個(gè)菱形
public:
explicit RhombusShift(QWidget* parent = nullptr);
protected:
void paintEvent(QPaintEvent*);
};
class TiltingBricks:public LoadingAnimBase{//三個(gè)正方形一個(gè)接一個(gè)傾斜倒向右側(cè)
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;//菱形內(nèi)部頂點(diǎn)和中心點(diǎn)的距離
static const int edgeGap = 2;//菱形頂點(diǎn)和外邊框的距離
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);//右側(cè)
const QPointF point3(x/2, y/2 + cornerGap + halfDiagonaly); //下方
const QPointF point4(edgeGap + halfDiagonalx,y/2); //左側(cè)
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;//每次移動(dòng)到四個(gè)節(jié)點(diǎn)上面,要靜止一段時(shí)間,這個(gè)值在0-90之間
for(int i = 0;i < 4;++i){
qreal proportion = 0;
const auto rest = fmod(mAngle,90);//余數(shù)
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 cornerGap = 2;
const int edgeLen = x/3;//小方塊邊長
const QRectF rct1(-edgeLen-cornerGap,-edgeLen-cornerGap,edgeLen,edgeLen);//左上
const QRectF rct2(-edgeLen-cornerGap,cornerGap,edgeLen,edgeLen);//左下
const QRectF rct3(cornerGap,cornerGap,edgeLen,edgeLen);//右下
const QRectF baseRectList[3] = {rct1,rct2,rct3};
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);
}
}
}
}
到此這篇關(guān)于Qt+QWidget實(shí)現(xiàn)簡約美觀的加載動(dòng)畫的文章就介紹到這了,更多相關(guān)Qt加載動(dòng)畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt利用tablewidget模擬手指實(shí)現(xiàn)滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Qt如何利用tablewidget模擬手指實(shí)現(xiàn)滑動(dòng)效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下2023-01-01
從零實(shí)現(xiàn)一個(gè)輕量級(jí)C++線程池
本文旨在構(gòu)建一個(gè)輕量級(jí)的、可擴(kuò)展的C++線池,文章詳細(xì)闡述了線程池的工作原理、核心組成部分及其設(shè)計(jì)思想,通過具體代碼展示了任務(wù)隊(duì)列、同步機(jī)制、任務(wù)接口等模塊的設(shè)計(jì)與實(shí)現(xiàn),需要的朋友可以參考下2026-04-04
c++將數(shù)組名作為函數(shù)參數(shù)對數(shù)組元素進(jìn)行相應(yīng)的運(yùn)算
這篇文章主要介紹了c++將數(shù)組名作為函數(shù)參數(shù)對數(shù)組元素進(jìn)行相應(yīng)的運(yùn)算,需要的朋友可以參考下2014-05-05
C語言文件操作實(shí)現(xiàn)數(shù)據(jù)持久化(幫你快速了解文件操作函數(shù))
持久數(shù)據(jù)其實(shí)就是將數(shù)據(jù)保存到數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于C語言文件操作實(shí)現(xiàn)數(shù)據(jù)持久化(幫你快速了解文件操作函數(shù))的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
詳談C與C++的函數(shù)聲明中省略參數(shù)的不同意義
下面小編就為大家分享一篇詳談C與C++的函數(shù)聲明中省略參數(shù)的不同意義,具有非常好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-11-11

