简述
很多时候,我们在实现页面页面显示时,经常要 show
或者 hide
页面,直接操作显得很生硬,体验度不好。所以很想在这期间,加上一个动画,用动画过度,让页面流畅,舒适。那么QTimeLine
类你不可错过。QTimeLine
类提供了用于控制动画的时间轴通常用于通过定期调用一个槽函数来动画一个 GUI 控件,一个动画是由很多张静态画面组成而每一个画面就是一帧图像。根据人是觉得暂留效应,每隔一定时间间隔就显示一帧图像当该间隔较短时人眼就感觉不出来了觉得看到的是连续的影像。
使用流程
构造对象
QTimeLine在构造函数中,你可以传递一个毫秒级的参数,设定动画的运行时间。如:
m_timLine = std::make_shared<QTimeLine>(600,this);
这里设置持续时间是600毫秒。这里是有默认值的,默认值是1000毫秒。
参数设置
1、设置帧数
m_timLine->setFrameRange(0,100);
这样表示动画分为100帧,然后每帧刷新的时候会产生一个信号, frameChanged()
这样,你就可以通过链接你的槽函数做你想做的事情。
2、设置增长曲线模式。
m_timLine->setCurveShape(QTimeLine::SineCurve);
这里设置为正弦曲线增长方式,其他的方式,请见后面参数详解。
3、信号绑定
connect(m_timLine.get(),&QTimeLine::valueChanged,this, &QtWidgetsDesktop::updateStep);
4、启动
最后一切准备就绪之后,调用start函数:
m_timLine->start();
参数详解
QTimeLine :: CurveShape
该枚举描述了QTimeLine值曲线的默认形状。默认形状是EaseInOutCurve。曲线定义了值和时间线之间的关系。
不变 | 值 | 描述 |
---|---|---|
QTimeLine::EaseInCurve |
0 |
该值开始缓慢增长,然后增加速度。 |
QTimeLine::EaseOutCurve |
1 |
该值开始稳定增长,然后缓慢结束。 |
QTimeLine::EaseInOutCurve |
2 |
值开始缓慢增长,然后稳定运行,然后再次缓慢增长。 |
QTimeLine::LinearCurve |
3 |
该值线性增长(例如,如果持续时间为1000 ms,则时间500 ms的值为0.5)。 |
QTimeLine::SineCurve |
4 |
该值以正弦形式增长。 |
QTimeLine::CosineCurve |
5 |
该值呈余弦形增长。 |
通过 setCurveShape()
进行设置. curveShape()
获取当前状态.
QTimeLine :: Direction
该枚举描述了处于 运行
状态时时间轴的方向。
不变 | 值 | 描述 |
---|---|---|
QTimeLine::Forward |
0 |
时间轴的当前时间随时间增加(即,从0移到结束/持续时间)。 |
QTimeLine::Backward |
1 |
时间轴的当前时间随时间减少(即,从结束/持续时间向0移动)。 |
通过 setDirection()
进行设置。 direction()
获取当前状态.
QTimeLine :: State
该枚举描述了时间轴的状态。
不变 | 值 | 描述 |
---|---|---|
QTimeLine::NotRunning |
0 |
时间轴未运行。这是QTimeLine的初始状态,完成后将重新进入QTimeLine状态。当前时间,帧和值将保持不变,直到调用setCurrentTime()或通过调用start()启动时间轴。 |
QTimeLine::Paused |
1 |
时间线已暂停(即暂时暂停)。调用setPaused(false)将恢复时间轴活动。 |
QTimeLine::Running |
2 |
时间轴正在运行。当控件处于事件循环中时,QTimeLine将定期更新其当前时间,并在适当的时候发出valueChanged()和frameChanged()。 |
通过 state()
获取当前状态, stateChanged()
获取改变状态。
使用案例
代码展示
这里实现了一个 QWidget
,当鼠标进入时,粉色图形从左往右,宽度渐渐增长,直到和父窗口相等。紫色图形,从右往左,宽度渐渐减小,直到为0。但鼠标离开时,情况正好相反。以下是代码。
//QtWidgetsDesktop.h
#pragma once
#include <QWidget>
#include <QFrame>
#include <memory>
class QLabel;
class QTimeLine;
class QtWidgetsDesktop : public QFrame
{
Q_OBJECT
public:
QtWidgetsDesktop(QFrame* parent = Q_NULLPTR);
protected slots:
void updateStep(qreal val);
protected:
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
private:
std::shared_ptr<QTimeLine> m_timLine;
std::shared_ptr<QLabel> m_labShowA;
std::shared_ptr<QLabel> m_labShowB;
};
//QtWidgetsDesktop.cpp
#include "QtWidgetsDesktop.h"
#include <QStyleOption>
#include <QPainter>
#include <QPushButton>
#include <QLabel>
#include <QTimeLine>
QtWidgetsDesktop::QtWidgetsDesktop(QFrame*parent)
: QFrame(parent)
{
this->resize(500, 309);
this->setWindowFlags(Qt::FramelessWindowHint);
this->setStyleSheet("background: #76AA71;");
m_labShowA = std::make_shared<QLabel>(this);
m_labShowB = std::make_shared<QLabel>(this);
m_labShowA->setStyleSheet("background: #FA8694;");
m_labShowB->setStyleSheet("background: #BDA1E2;");
m_labShowB->resize(this->width(), this->height() / 5 * 2);
m_labShowB->move(0, this->height() / 5 * 3);
m_timLine = std::make_shared<QTimeLine>(600,this);
m_timLine->setFrameRange(0, 100);
connect(m_timLine.get(),&QTimeLine::valueChanged,this, &QtWidgetsDesktop::updateStep);
}
void QtWidgetsDesktop::updateStep(qreal val)
{
QTimeLine::Direction type = m_timLine->direction();
if (type == QTimeLine::Forward)
{
m_labShowA->resize(val * this->width(), this->height() / 5 * 2);
m_labShowB->resize((this->width() - val * this->width()), this->height() / 5 * 2);
}
else {
m_labShowA->resize(val * this->width(), this->height() / 5 * 2);
m_labShowB->resize((this->width() - val * this->width()), this->height() / 5 * 2);
}
}
void QtWidgetsDesktop::enterEvent(QEvent* event)
{
m_timLine->setDirection(QTimeLine::Forward);
if (m_timLine->state() != QTimeLine::Running)
{
m_timLine->start();
}
}
void QtWidgetsDesktop::leaveEvent(QEvent* event)
{
m_timLine->setDirection(QTimeLine::Backward);
if (m_timLine->state() != QTimeLine::Running)
{
m_timLine->start();
}
}
结果展示
CurveShape
设置为: EaseOutCurve CurveShape
设置为: LinearCurve CurveShape
设置为: SineCurve