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.”,大概就是“非窗口的部件是子部件,显示在它们的父部件中”。看来这就是问题所在。

因此我就直接换掉基类了。。当然客官也可以尝试用其他方法试试。。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值