QPropertyAnimation - Qt widget 淡入淡出效果(二)

在上一面一篇文章中,已經基本實現了淡入淡出的效果。但是不足的地方是,所有的代碼都是寫在主程序裏的。這對於寫項目來講,肯定是不合適的,最好能做成自定義的類,調用起來纔會舒服。於是,我們接下來繼續改造。改造之前,我們我們先確定一下思路。

1. 新建類的.h和.cpp文件,命名爲:fadeinwidget.h和fadeinwidget.cpp

2. 該子類繼承於QStackedWidget(這裏爲什麼集成QStackedWidget類,後面會講到)

3. 該類可以調用函數來啓動淡出和淡入的效果,並且可以設定動畫時間

目標明確後,我們就對原先的代碼進行改造了。。

fadeinwidget.h:

#ifndef FADEINWIDGET_H
#define FADEINWIDGET_H

#include <QWidget>
#include <QAbstractAnimation>
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
#include <QStackedWidget>

#define QT_NO_OPENGL

class FadeInWidget : public QStackedWidget
{
    Q_OBJECT
public:
    explicit FadeInWidget(QWidget *parent = 0);

signals:

public:
    void Start_Animation(enum QAbstractAnimation::Direction);
    void Set_Duration(int DurationTime);

private slots:
    void animation_finished(void);
    void animation_stateChanged(QAbstractAnimation::State newState,
                                   QAbstractAnimation::State oldState);

private:
    QGraphicsOpacityEffect  *Opacity;
    QPropertyAnimation      *Animation;
    int                     animationDuration;

    enum QAbstractAnimation::Direction direction;
};

#endif // FADEINWIDGET_H

fadeinwidget.cpp:

#include "fadeinwidget.h"
#include <QDebug>

FadeInWidget::FadeInWidget(QWidget *parent) : QStackedWidget(parent)
{
    //this->setWindowFlags(Qt::Window);

    Opacity = nullptr,
    animationDuration = 1000;

    Opacity = new QGraphicsOpacityEffect(this);
    this->setGraphicsEffect(Opacity);
    Opacity->setOpacity(1);

    Animation = new QPropertyAnimation(Opacity, "opacity", this);
    Animation->setStartValue(1);
    Animation->setEndValue(0);
    Animation->setDuration(animationDuration);
    Animation->setEasingCurve(QEasingCurve::Linear);

    connect(Animation, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
            this, SLOT(animation_stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))
            );
    connect(Animation, SIGNAL(finished()),this, SLOT(animation_finished()));
}

void FadeInWidget::animation_stateChanged(QAbstractAnimation::State newState,
                                       QAbstractAnimation::State oldState) {

    if (newState != QAbstractAnimation::Running) {
            Animation->setDirection(direction);
    }
}

void FadeInWidget::Start_Animation(enum QAbstractAnimation::Direction m_direction)
{
    if(this->isHidden())//如果控件隱藏,則顯示出來
    {
        this->show();
    }

    if (Animation->state() != QAbstractAnimation::Stopped) {
        Animation->pause();
    }

    //when the animation stats,the stateChanged() signal is emitted.
    direction = m_direction;
    Animation->start();
}

void FadeInWidget::animation_finished(void)
{
    if(Animation->direction() == QAbstractAnimation::Backward)
    {
        qDebug()<<"hide";
        this->hide();
    }
}

void FadeInWidget::Set_Duration(int DurationTime)
{
    animationDuration = DurationTime;

    Animation->setDuration(animationDuration);
}

主程序調用方法,我這裏用一個定時器不停去觸發動畫效果。。

#include "mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setWindowFlags(Qt::FramelessWindowHint);

    m_widget = new FadeInWidget;
    m_widget->setGeometry(QRect(0,0,400,400));
    m_widget->setStyleSheet("background-color: rgb(255, 85, 0);");
    m_widget->setParent(this);
    m_widget->Set_Duration(300);
    m_widget->show();

    Mytimer = new QTimer(this);
    connect(Mytimer,SIGNAL(timeout()),SLOT(Timer_Function()));
    Mytimer->start(3000);
}

MainWindow::~MainWindow()
{

}

void MainWindow::Timer_Function(void)
{
    static bool flag = 0;

    if(flag)flag = 0;
    else flag = 1;
    qDebug()<<"flag is "<<flag;

    if(flag)m_widget->Start_Animation(QAbstractAnimation::Backward);
    else m_widget->Start_Animation(QAbstractAnimation::Forward);
}

最終效果如下:

最後,在提到一下爲什麼我直接繼承了QStackedWidget,而不是QWidget類。我也是初學者,問題可能是在於QWidget類可能有分自帶窗口的和不帶窗口的。反正我剛開始繼承QWidget類,在主函數中,怎麼都show不出來。後來纔看到如下的這篇文章:

https://blog.csdn.net/u013267480/article/details/49645093

有提到,而Qt的文檔上有這麼一句話:“Non-window widgets are child widgets, displayed within their parent widgets.”,大概就是“非窗口的部件是子部件,顯示在它們的父部件中”。看來這就是問題所在。

因此我就直接換掉基類了。。當然客官也可以嘗試用其他方法試試。。

發佈了109 篇原創文章 · 獲贊 39 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章