在上一面一篇文章中,已經基本實現了淡入淡出的效果。但是不足的地方是,所有的代碼都是寫在主程序裏的。這對於寫項目來講,肯定是不合適的,最好能做成自定義的類,調用起來纔會舒服。於是,我們接下來繼續改造。改造之前,我們我們先確定一下思路。
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.”,大概就是“非窗口的部件是子部件,顯示在它們的父部件中”。看來這就是問題所在。
因此我就直接換掉基類了。。當然客官也可以嘗試用其他方法試試。。