Qt+QWidget實(shí)現(xiàn)簡(jiǎn)約美觀的加載動(dòng)畫
給大家分享兩個(gè)小方塊風(fēng)格的加載動(dòng)畫
第五季來(lái)啦
效果如下:
一個(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;// 菱形的邊長(zhǎng) const int halfDiagonalx = (x/2 - edgeGap - cornerGap )/2;//水平方向一半對(duì)角線長(zhǎng)度 const int halfDiagonaly = (y/2 - edgeGap - cornerGap )/2;//垂直方向一半對(duì)角線長(zhǎng)度 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;//小方塊邊長(zhǎng) 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)簡(jiǎn)約美觀的加載動(dòng)畫的文章就介紹到這了,更多相關(guān)Qt加載動(dòng)畫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)踐排序函數(shù)模板項(xiàng)目的參考方法
今天小編就為大家分享一篇關(guān)于C++實(shí)踐排序函數(shù)模板項(xiàng)目的參考方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02C語(yǔ)言之sizeof與strlen的使用及區(qū)別
這篇文章主要介紹了C語(yǔ)言之sizeof與strlen的使用及區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07使用CMake構(gòu)建一個(gè)簡(jiǎn)單的C++項(xiàng)目的實(shí)現(xiàn)
CMake是一個(gè)跨平臺(tái)的自動(dòng)化構(gòu)建工具,可以用于構(gòu)建各種類型的項(xiàng)目,本文主要介紹了使用CMake構(gòu)建一個(gè)簡(jiǎn)單的C++項(xiàng)目,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10C++實(shí)現(xiàn)LeetCode(18.四數(shù)之和)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(18.四數(shù)之和),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++?自增自減運(yùn)算符的實(shí)現(xiàn)示例
本文主要介紹了C++?自增自減運(yùn)算符的實(shí)現(xiàn)示例,自增和自減運(yùn)算符在C++中主要用于循環(huán)語(yǔ)句中,使循環(huán)變量的值自動(dòng)+1或者-1,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Linux中rm命令使用以及C/C++代碼實(shí)現(xiàn)
m 是remove 的縮寫,Linux中 rm 命令的功能為刪除一個(gè)目錄中的一個(gè)或多個(gè)文件或目錄,它也可以將某個(gè)目錄及其下的所有文件及子目錄均刪除,這篇文章主要給大家介紹了關(guān)于Linux中rm命令使用以及C/C++代碼實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2022-04-04