c++ - 如何使用 QTimeLine 为两个值设置动画

标签 c++ qt animation qt4 qgraphicsitem

我有一个QGraphicsItem,我想为它制作尺寸变化的动画。因此,我需要随时间改变对象的 heightwidth。我过去曾将 QTimeLine 用于单变量动画,如果可能的话,我想在这里将其用于双变量动画。但是,我没有看到适用于两个变量的 QTimeLine::setFrameRange()

我怎样才能做到这一点?有更好的 Qt 类吗?

最佳答案

由于动画必须附加到对象上,您的图形项将是一个 QGraphicsObject,因此您可以将相关属性公开给 Qt 属性系统。

由于您要为相当于 QSizeF 的内容设置动画,因此最简单的方法是将其作为单个属性公开并使用 QPropertyAnimation

一般来说,如果您必须同时为多个属性设置动画,请将它们设置为单独的 QPropertyAnimation。然后使用 QParallelAnimationGroup 并行运行它们。

当然可以使用QTimeLine,但是您必须手动在端点之间进行插值,例如,基于帧号。何必呢。

下面是一个完整的示例,展示了如何同时为三个属性设置动画:possizerotation

main.cpp

#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QSequentialAnimationGroup>
#include <QGraphicsObject>
#include <QPainter>
#include <QApplication>

class Item : public QGraphicsObject {
    Q_OBJECT
    qreal m_pen;
    QSizeF m_size;
    Q_PROPERTY(QSizeF size READ size WRITE setSize NOTIFY newSize)
    Q_SIGNAL void newSize();
    qreal width() const { return m_size.width() + m_pen; }
    qreal height() const { return m_size.height() + m_pen; }
public:
    explicit Item(QGraphicsItem *parent = 0) :
        QGraphicsObject(parent), m_pen(5.0), m_size(50.0, 50.0) {}
    QSizeF size() const { return m_size; }
    void setSize(const QSizeF & size) {
        if (m_size != size) {
            m_size = size;
            update();
            emit newSize();
        }
    }
    QRectF boundingRect() const {
        return QRectF(-width()/2, -height()/2, width(), height());
    }
    void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
        p->setPen(QPen(Qt::black, m_pen));
        p->drawEllipse(QPointF(0,0), width()/2, height()/2);
        p->setPen(QPen(Qt::red, m_pen));
        p->drawLine(0, 0, 0, height()/2);
    }
};

void animate(QObject * obj)
{
    QParallelAnimationGroup * group = new QParallelAnimationGroup(obj);
    QPropertyAnimation * pos = new QPropertyAnimation(obj, "pos", obj);
    QPropertyAnimation * size = new QPropertyAnimation(obj, "size", obj);
    QPropertyAnimation * rot= new QPropertyAnimation(obj, "rotation", obj);
    pos->setDuration(3000);
    pos->setLoopCount(-1);
    pos->setEasingCurve(QEasingCurve::InOutCubic);
    pos->setStartValue(QPointF(-50, -50));
    pos->setEndValue(QPointF(50, 50));
    size->setDuration(1500);
    size->setLoopCount(-1);
    size->setEasingCurve(QEasingCurve::InOutElastic);
    size->setStartValue(QSizeF(100, 100));
    size->setEndValue(QSizeF(100, 30));
    rot->setDuration(1000);
    rot->setLoopCount(-1);
    rot->setStartValue(0.0);
    rot->setEndValue(360.0);
    group->addAnimation(pos);
    group->addAnimation(size);
    group->addAnimation(rot);
    group->start();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene s;
    QGraphicsView v(&s);
    Item * item = new Item;
    s.addItem(item);
    v.setRenderHint(QPainter::Antialiasing);
    v.setSceneRect(-125, -125, 300, 300);
    v.show();
    animate(item);
    return a.exec();
}

#include "main.moc"

关于c++ - 如何使用 QTimeLine 为两个值设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18599617/

相关文章:

qt - 如何使用 QPlaintTextEdit 有效地创建固定宽度的列记录器?

qt - 将填充有文件名的 QListWidget 中的选定项目复制到剪贴板,但作为文件(不是文本)

安卓背景动画滞后游戏

python - Matplotlib: 'module'对象没有属性 'FFMpegWriter'/'Writer'

c++ - 使用 qmake 将 dll 安装到 2 个目标(路径)中

c++ - 分离并打印出偶数和奇数随机数

c++ - 将 STL 算法与 Qt 容器结合使用

jQuery fadeOut/fadeIn 未按预期工作?

c++ - 为什么在 NDS 上整数处理速度比字节快?

php - 如何为 8 名玩家创建 7 轮的独特玩家组合