一般在Qt实现动画可以用QAbstractAnimation的子类实现。这里给出一个不一样的例子实现动画,即用QTimeLine实现。功能是有一个QStackedWidget,它有两个子页面。默认显示第一页。点击“动画”按钮播放一段动画使页面第一页滑动到第二页,然后切换到第二页。程序测试环境是VS2017和Qt5.9。下面是程序的两张截图:
头文件:
/* 我们用视觉效果绘制两个子Widget同时出现的效果 */ class MSlideEffect : public QGraphicsEffect { Q_OBJECT Q_PROPERTY(qreal ratio READ ratio WRITE setRatio) public: MSlideEffect(QObject *parent = 0); void setFirstWidget(QWidget* first); void setSecondWidget(QWidget* second); qreal ratio() const; void setRatio(qreal ratio); private: void draw(QPainter *painter) override; private: qreal moveRatio; // [0,1] QPixmap p1; QPixmap p2; };
CPP文件。下述代码中QtTest是主窗口类。为了简单在主窗口里只有一个QStackedWidget,它是ui.swSelect。ui.swPage1和ui.swPage2是ui.swSelect的两个子页面。另外,下方代码中的QTimeLine*可以手动释放,而不必等到程序结束才释放:
QtTest::QtTest(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); } //--------------------------------------------------------------------------------------- // 播放第一页切换到第二页的滑动动画 //--------------------------------------------------------------------------------------- void QtTest::on_pbFlash_clicked() { MSlideEffect* effect = new MSlideEffect(this); effect->setFirstWidget(ui.swPage1); effect->setSecondWidget(ui.swPage2); ui.swSelect->setGraphicsEffect(effect); QTimeLine* timeLine = new QTimeLine(250, this); timeLine->setFrameRange(0, 500); timeLine->setCurveShape(QTimeLine::EaseInOutCurve); connect(timeLine, &QTimeLine::frameChanged, this, [effect](int frame) { effect->setRatio(frame / 500.0); }); connect(timeLine, &QTimeLine::finished, this, [this]() { ui.swSelect->setCurrentIndex(1); ui.swSelect->setGraphicsEffect(0); }); timeLine->start(); /* 播放动画的时候隐藏它们 */ /* 因为在某些情况下它会影响动画显示 */ ui.swPage1->hide(); ui.swPage2->hide(); } ///////////////////////////////////////////////////////////////////////////////////////// MSlideEffect::MSlideEffect(QObject *parent) : QGraphicsEffect(parent) { moveRatio = 0; } void MSlideEffect::setFirstWidget(QWidget* first) { p1 = first->grab(); } void MSlideEffect::setSecondWidget(QWidget* second) { second->resize(p1.size()); p2 = second->grab(); } void MSlideEffect::draw(QPainter *painter) { int full = p1.width(); int offset = int(full * moveRatio); painter->translate(-offset, 0); painter->drawPixmap(0, 0, p1); painter->drawPixmap(full, 0, p2); } qreal MSlideEffect::ratio() const { return moveRatio; } void MSlideEffect::setRatio(qreal ratio) { moveRatio = ratio; update(); }
标签:动画,ratio,void,QTimeLine,ui,滑动,MSlideEffect From: https://www.cnblogs.com/mengxiangdu/p/17921610.html