8000 QStackWidget动画(1) · Issue #70 · holdyounger/ScopeBlog · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
QStackWidget动画(1) #70
Open
@holdyounger

Description

@holdyounger

QStackWidget动画(1)

使用直接提升为组件为当前组件即可。

.h

#ifndef QANIMATIONSTACKEDWIDGET_H
#define QANIMATIONSTACKEDWIDGET_H

#include <QStackedWidget>
#include <QVariant>

class QPropertyAnimation;
class QGraphicsOpacityEffect;
class QParallelAnimationGroup;
//class QVariant;

class QAnimationStackedWidget : public QStackedWidget
{
    Q_OBJECT
public:
    explicit QAnimationStackedWidget(QWidget *parent = Q_NULLPTR);

    ~QAnimationStackedWidget();

    void Next();

    void SwitchToIndex(int NextIndex, bool bFront = true);

    void setCurrentWidget(QWidget* widget);
protected:
    void paintEvent(QPaintEvent *e);

private:
    QParallelAnimationGroup* m_ParlGroup;

    QPropertyAnimation *m_pAnimPrty;

    QGraphicsOpacityEffect* m_pAnimGraphicsEffect;
    QPropertyAnimation* m_pAnimGraphics;

    bool m_bAnimation;

    int m_nDuration;

    int m_nWidgetCount;

    int m_nNextIndex;

    QVariant m_nCurValue;

    bool m_bMoveFront;

private:
    void Init();

    void paintPrevious(QPainter &paint, int currentIndex);

    void paintNext(QPainter &paint, int nextIndex);

    void moveAnimationStart(bool bEnter);

private slots:
    void slotAnimationValueChanged(QVariant value);

    void slotAnimationFinished();
};

#endif // QANIMATIONSTACKEDWIDGET_H

.cpp

#include "QAnimationStackedWidget.h"

#include <QPropertyAnimation>
#include <QPainter>
#include <QParallelAnimationGroup>
#include <QGraphicsOpacityEffect>

QAnimationStackedWidget::QAnimationStackedWidget(QWidget *parent) :
    QStackedWidget(parent)
{
    Init();
}

QAnimationStackedWidget::~QAnimationStackedWidget()
{

}

void QAnimationStackedWidget::Init()
{
    m_bAnimation = false;

    m_nDuration = 350;

    m_ParlGroup = new QParallelAnimationGroup();

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

	m_pAnimGraphics = new QPropertyAnimation(m_pAnimGraphicsEffect, "opacity");
    m_pAnimPrty = new QPropertyAnimation(this, QByteArray());
    connect(m_pAnimPrty, SIGNAL(valueChanged(QVariant)), this, SLOT(slotAnimationValueChanged(QVariant)));
    connect(m_pAnimPrty, SIGNAL(finished()), this, SLOT(slotAnimationFinished()));

    m_pAnimPrty->setEasingCurve(QEasingCurve::InOutQuad);
    m_pAnimGraphics->setEasingCurve(QEasingCurve::InOutQuad);

	m_ParlGroup->addAnimation(m_pAnimPrty);
	m_ParlGroup->addAnimation(m_pAnimGraphics);

}

void QAnimationStackedWidget::slotAnimationValueChanged(QVariant value)
{
    m_nCurValue = value;

    update();
}

void QAnimationStackedWidget::slotAnimationFinished()
{
    m_bAnimation = false;

    widget(currentIndex())->show();

    setCurrentIndex(m_nNextIndex);
}

void QAnimationStackedWidget::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e)

    if(m_bAnimation)
    {
        QPainter paint(this);

        if (m_bMoveFront)
        {
            //绘制当前Widget
            paintPrevious(paint, currentIndex());

            //绘制下一个widget
            paintNext(paint, m_nNextIndex);
        }
        else
        {
            //绘制当前Widget
            paintPrevious(paint, m_nNextIndex);

            //绘制下一个widget
            paintNext(paint, currentIndex());
        }
    }
}

void QAnimationStackedWidget::paintPrevious(QPainter &paint, int currentIndex)
{
    //获得当前页面的Widget
    QWidget *w = widget(currentIndex);

    // 切换过程窗口的背景色
    QString strStyle = QString("#%1{background-color: #FFFFFF}").arg(w->objectName());

    w->setStyleSheet(strStyle);

    QPixmap pixmap(w->size());

    //将Widget的内容渲染到QPixmap对象中,即将Widget变成一张图片
    w->render(&pixmap);

    QRect r = w->geometry();

    //绘制当前的Widget
    double value = m_nCurValue.toDouble();
    QRectF r1(0.0, 0.0, value, r.height());
    QRectF r2(r.width() - value, 0, value, r.height());
    paint.drawPixmap(r1, pixmap, r2);
}

void QAnimationStackedWidget::paintNext(QPainter &pain
6E96
t, int nextIndex)
{
    QWidget *nextWidget = widget(nextIndex);

    QString strStyle = QString("#%1{background-color: #FFFFFF}").arg(nextWidget->objectName());

    nextWidget->setStyleSheet(strStyle);

    QRect r = geometry();

    //这行代码不加会有bug,第一次切换的时候,QStackedWidget并没有为child分配大小
    nextWidget->resize(r.width(), r.height());
    QPixmap nextPixmap(nextWidget->size());

    nextWidget->render(&nextPixmap);
    double value = m_nCurValue.toDouble();
    QRectF r1(value, 0.0, r.width() - value, r.height());
    QRectF r2(0.0, 0.0, r.width() - value, r.height());

    paint.drawPixmap(r1, nextPixmap, r2);
}

void QAnimationStackedWidget::moveAnimationStart(bool bEnter)
{
	if (bEnter)
	{
		m_pAnimPrty->setStartValue(this->width());
		m_pAnimPrty->setEndValue(0);

		m_pAnimGraphics->setDuration(m_nDuration);
		m_pAnimGraphics->setStartValue(0);
		m_pAnimGraphics->setEndValue(1);
	}
	else
	{
		m_pAnimPrty->setStartValue(0);
		m_pAnimPrty->setEndValue(this->width());

		m_pAnimGraphics->setDuration(m_nDuration);
		m_pAnimGraphics->setStartValue(0);
		m_pAnimGraphics->setEndValue(1);
	}

	m_pAnimPrty->setDuration(m_nDuration);

	// m_pAnimPrty->start();

	m_ParlGroup->start();
}

void QAnimationStackedWidget::SwitchToIndex(int index, bool bFront)
{
    //如果正在动画,那么return
    int curIndex = currentIndex();

    m_bMoveFront = bFront;
    m_bAnimation = true;
    m_nWidgetCount = count();

    m_nNextIndex = index;

    //隐藏当前的widget
    widget(curIndex)->hide();

    //开始动画并设置间隔和开始、结束值
    QRect g = geometry();

    int width = g.width();

    bFront = index >= curIndex;

    moveAnimationStart(bFront);
}

void QAnimationStackedWidget::setCurrentWidget(QWidget* widget)
{
	int index = indexOf(widget);
    SwitchToIndex(index);
}

void QAnimationStackedWidget::Next()
{
    //如果正在动画,那么return
    if(m_bAnimation)
    {
        return;
    }

    m_bAnimation = true;
    m_nWidgetCount = count();
    int nIndex = currentIndex();

    //计算下一页的索引
    m_nNextIndex = (nIndex + 1) % m_nWidgetCount;

    //隐藏当前的widget
    widget(nIndex)->hide();

    //开始动画并设置间隔和开始、结束值
    QRect g = geometry();
    int x = g.x();
    int width = g.width();
    m_pAnimPrty->setStartValue(width);
    m_pAnimPrty->setEndValue(0);
    m_pAnimPrty->setDuration(m_nDuration);
    m_pAnimPrty->start();

    Q_UNUSED(x)
}

blog link QStackWidget动画(1)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0