Qt动画框架-(2)Qt动画和属性

Qt动画和Qt类属性

QPropertyAnimation类可以在Qt属性中进行插值。
属性值一般是类中的get/set方法,或者直接查看源码:

    //QWidget的属性(一部分)
    Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
    Q_PROPERTY(QRect frameGeometry READ frameGeometry)
    Q_PROPERTY(QRect normalGeometry READ normalGeometry)
    Q_PROPERTY(int x READ x)
    Q_PROPERTY(int y READ y)

通常这个类应该用于动画直接设置值,事实上,它的父类QVariantAnimation,有一个updateCurrentValue()的空实现,除非我们在valuechange的信号上改变它,否则它不会改变任何值。
我们选择让Qt属性动起来的一个主要原因是它为我们提供了在Qt API中激活现有类的自由。值得注意的是,QWidget类(我们也可以嵌入到QGraphicsView中)有其边界、颜色等属性。

  • 线性插值动画例子
    Widget w;
    QLabel pix;

    pix.setPixmap(QPixmap("E:/pic/poi2.jpg"));
    pix.setParent(&w);

    w.addItem(&pix);
    w.show();

    QPropertyAnimation animation(&w, "geometry");
    animation.setDuration(2000);

    QDesktopWidget desktop;

    animation.setStartValue(QRect(desktop.width() / 2,
                            desktop.height() / 2,
                            pix.width(),
                            pix.height()));
    animation.setEndValue(QRect(desktop.width() / 2,
                          0,
                          pix.width(),
                          pix.height()));

    animation.start();

其中Widget继承自QWidget,addItem实现如下(下文的addItem也是此函数)

void addItem(QWidget *item)
{
    if(item == nullptr)
    {
        return;
    }
    if(layout() == nullptr)
    {
        QGridLayout* l = new QGridLayout;
        l->addWidget(item);
        setLayout(l);
    }
    else
    {
        QGridLayout* l = static_cast<QGridLayout*>(layout());
        l->addWidget(item);
    }
}

该动画的效果
这里写图片描述
图1 动画示例
动画解释:从屏幕中心(desktop.width() / 2,desktop.height() / 2)上升到屏幕最上方(QRect(desktop.width() / 2,0)时间总长度为2s(animation.setDuration(2000))。

  • 插值动画

上面的例子将在开始值和结束值之间进行线性插值。还可以设置位于开始和结束值之间的值。插值就会被这些点所利用。
更改部分代码

    animation.setKeyValueAt(0, QRect(desktop.width() / 2,
                            desktop.height() / 2,
                            pix.width(),
                            pix.height()));
    animation.setKeyValueAt(0.7, QRect(desktop.width() / 2,
                          0,
                          pix.width(),
                          pix.height()));
    animation.setKeyValueAt(1, QRect(desktop.width() / 2,
                            desktop.height() / 2,
                            pix.width(),
                            pix.height()));

    animation.start();

该动画效果
这里写图片描述
图2 插值动画
动画解释:从屏幕中心上升到屏幕最上方,然后回到出发点,各比例setKeyValueAt的第一个参数时间总长度为2s。

  • Qt属性

您还可以为未声明为Qt属性的QObject的值生成动画。唯一的要求是这个值有一个setter。然后,您可以对包含该值的类进行子类化,并声明使用此setter的属性。请注意,每个Qt属性都需要一个getter,所以如果没有定义,您将需要自己提供一个getter。

class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
{
    Q_OBJECT
    Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
};

在上面的代码示例中,我们子类QGraphicsRectItem并定义几何属性。即使QGraphicsRectItem不提供几何属性,我们现在也可以对窗口小部件的几何图形进行动画处理。(关于Qt属性的章节将在后期更新)

  • 动画和图形视图框架

当您想要动画QGraphicsItem时,您也可以使用QPropertyAnimation。但是,QGraphicsItem不会继承QObject。一个很好的解决方案是将您想要动画化的图形项子化。这个类也会继承QObject。这样,QPropertyAnimation可以用于QGraphicsItem。下面的例子显示了如何完成。另一种方法是继承QGraphicsWidget,它已经是一个QObject。

class Pixmap : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
    Q_PROPERTY(QPointF pos READ pos WRITE setPos)
    ...

特别注意,QObject必须是元元对象系统要求的第一个类。

  • 简单的曲线动画

如前所述,QPropertyAnimation在开始和结束属性值之间执行插值。除了为动画添加更多的键值之外,您还可以使用缓动曲线。缓和曲线描述了一种控制0和1之间内插速度的函数的功能,如果要在不改变插值路径的情况下控制动画速度,则该方法很好用。
在第一个线性插值动画代码中添加一句即可

animation.setEasingCurve(QEasingCurve::OutBounce);

实现效果
这里写图片描述
图3 曲线动画

通过设置QEasingCurve可以实现很多不同的效果
这里写图片描述
详细需要查看文档,总大概40多个 ==

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值