在上一面一篇文章中,已经基本实现了淡入淡出的效果。但是不足的地方是,所有的代码都是写在主程序里的。这对于写项目来讲,肯定是不合适的,最好能做成自定义的类,调用起来才会舒服。于是,我们接下来继续改造。改造之前,我们我们先确定一下思路。
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.youkuaiyun.com/u013267480/article/details/49645093
有提到,而Qt的文档上有这么一句话:“Non-window widgets are child widgets, displayed within their parent widgets.”,大概就是“非窗口的部件是子部件,显示在它们的父部件中”。看来这就是问题所在。
因此我就直接换掉基类了。。当然客官也可以尝试用其他方法试试。。