Unsolved How can I optimize a animation I make for QTabWidget
-
Hi
I have written a class inheritancedQTabWidget
withQPropertyAnimation
.It can work but I think it is so expensive.
Could you give me some suggestions?
#ifndef CANIMATIONTABWIDGET_H #define CANIMATIONTABWIDGET_H #include <QPainter> #include <QVariant> #include <QTabWidget> #include <QPropertyAnimation> class CAnimationTabWidget : public QTabWidget { Q_OBJECT public: enum AnimationType { TopToBottom, BottomToTop, LeftToRight, RightToLeft }; explicit CAnimationTabWidget(QWidget *parent = 0); virtual ~CAnimationTabWidget(); void start(int index); void setLength(int length, AnimationType type); void setDuration(int duration); int getDuration() const; private slots: void valueChanged(const QVariant &value); void animationStarted(QAbstractAnimation::State before, QAbstractAnimation::State after); void animationFinished(); protected: virtual void paintEvent(QPaintEvent *event); void renderPreviousWidget(QPainter &painter, QTransform &transform); void renderCurrentWidget(QPainter &painter, QTransform &transform); private: bool m_PaintSwitch; bool m_isAnimating; int m_currentValue; int m_currentIndex, m_previousIndex; AnimationType m_type; QPropertyAnimation *m_animation; }; #endif // CANIMATIONTABWIDGET_H #include "CAnimationTabWidget.h" #include <QDebug> #include <QTabBar> CAnimationTabWidget::CAnimationTabWidget(QWidget *parent) : QTabWidget(parent), m_isAnimating(false), m_currentValue(0), m_currentIndex(0), m_previousIndex(0) { m_animation = new QPropertyAnimation(this, QByteArray()); m_animation->setDuration(500); m_animation->setEasingCurve(QEasingCurve::OutSine); m_animation->setStartValue(0); m_animation->setEndValue(0); connect(m_animation, SIGNAL(valueChanged(QVariant)), SLOT(valueChanged(QVariant))); connect(m_animation, SIGNAL(finished()), SLOT(animationFinished())); } CAnimationTabWidget::~CAnimationTabWidget() { delete m_animation; } void CAnimationTabWidget::start(int index) { if(m_isAnimating) { m_animation->stop(); m_isAnimating = false; } m_previousIndex = m_currentIndex; m_currentIndex = index; if(m_previousIndex == m_currentIndex) { qDebug()<<"same index"; return; } int offsetx = frameSize().width(); int offsety = frameSize().height(); widget(m_currentIndex)->setGeometry(0, 0, offsetx, offsety); currentWidget()->hide(); m_isAnimating = true; m_animation->start(); } void CAnimationTabWidget::setLength(int length, CAnimationTabWidget::AnimationType type) { switch(m_type = type) { case BottomToTop : case LeftToRight : { m_animation->setStartValue(-length/2); m_animation->setEndValue(length/2); break; } case TopToBottom : case RightToLeft : { m_animation->setStartValue(length/2); m_animation->setEndValue(-length/2); break; } } } void CAnimationTabWidget::setDuration(int duration) { m_animation->setDuration(duration); } int CAnimationTabWidget::getDuration() const { return m_animation->duration(); } void CAnimationTabWidget::valueChanged(const QVariant &value) { m_currentValue = value.toInt(); update(); } void CAnimationTabWidget::animationStarted(QAbstractAnimation::State before ,QAbstractAnimation::State after) { qDebug()<<before<<after; } void CAnimationTabWidget::animationFinished() { m_currentValue = 0; m_isAnimating = false; QWidget *w = widget(m_currentIndex); w->show(); w->raise(); setCurrentWidget( w ); update(); } void CAnimationTabWidget::paintEvent(QPaintEvent *event) { if(m_isAnimating) { // raise(); QPainter painter(this); QTransform transform; renderCurrentWidget(painter, transform); renderPreviousWidget(painter, transform); // lower(); } else { QWidget::paintEvent(event); } } void CAnimationTabWidget::renderPreviousWidget(QPainter &painter, QTransform &transform) { QWidget *w = widget(m_previousIndex); QPixmap pixmap( w->size() ); w->render(&pixmap,QPoint(),QRegion(),RenderFlags(DrawChildren)); Q_UNUSED(transform); switch(m_type) { case BottomToTop : { painter.drawPixmap(tabBar()->width(), height()/2, pixmap); break; } case TopToBottom : { painter.drawPixmap(tabBar()->width(), -height()/2, pixmap); break; } case LeftToRight : { painter.drawPixmap(width()/2, 0, pixmap); break; } case RightToLeft : { painter.drawPixmap(-width()/2, 0, pixmap); break; } } } void CAnimationTabWidget::renderCurrentWidget(QPainter &painter, QTransform &transform) { QWidget *w = widget(m_currentIndex); QPixmap pixmap( w->size() ); w->render(&pixmap,QPoint(),QRegion(),RenderFlags(DrawChildren)); switch(m_type) { case BottomToTop : { transform.translate(0, m_currentValue); painter.setTransform(transform); painter.drawPixmap(tabBar()->width(), -height()/2, pixmap); break; } case TopToBottom : { transform.translate(0, m_currentValue); painter.setTransform(transform); painter.drawPixmap(tabBar()->width(), height()/2, pixmap); break; } case LeftToRight : { transform.translate(m_currentValue, 0); painter.setTransform(transform); painter.drawPixmap(-width()/2, 0, pixmap); break; } case RightToLeft : { transform.translate(m_currentValue, 0); painter.setTransform(transform); painter.drawPixmap(width()/2, 0, pixmap); break; } } }
Regards
Mihan