如何使用动画更改QGraphicsPixmap的大小

How to change size of QGraphicsPixmap using animation?

本文关键字:QGraphicsPixmap 何使用 动画      更新时间:2023-10-16

我有一个名为Pixmap的类派生自QGraphicsPixmapItem和StartScreen类派生自QGraphicsScene。我想使用动画(QPropertyAnimation 类(在特定时间范围内调整显示图像的大小。其他操作(如设置位置或旋转(不是问题,但我找不到任何属性,如大小(例如setSize((方法(。我怎样才能以另一种方式做到这一点?感谢您的提前。

StartScreen::StartScreen(int windowWidth, int windowHeight)
{
    setSceneRect(0, 0, windowWidth, windowHeight);
    setBackgroundBrush(QBrush(QImage(":/images/background.png")));
    Pixmap * logo = new Pixmap(":/images/logo.png");
    addItem(logo);
    logo->setPos((windowWidth - logo->pixmap().width()) / 2, (windowWidth - logo->pixmap().width()) / 2 - 75);
    //QPropertyAnimation * animation = new QPropertyAnimation(logo, "");
}

QPropertyAnimation适用于Qt属性,但只有继承自QObject的对象才具有Qt属性,因此,如果要使用动画,可以使用QGraphicsObject创建自己的项目,或者创建一个继承所需项并QObject的类。

class Pixmap: public QObject, public QGraphicsPixmapItem{
    Q_OBJECT
    Q_PROPERTY(qreal scale READ scale WRITE setScale)
    Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
    Q_PROPERTY(QPointF pos READ pos WRITE setPos)
public:
    using QGraphicsPixmapItem::QGraphicsPixmapItem;
};

在前面的例子中,利用QGraphicsItem及其派生类具有方法pos()setPos()scale()setScale()rotation()setRotation(),因此仅在Q_PROPERTY中使用它们。

在下一部分中,我将展示一个例子:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsView w;
    QGraphicsScene scene(0, 0, 640, 480);
    w.setScene(&scene);
    w.show();
    Pixmap* logo = new Pixmap(QPixmap(":/image.jpg"));
    scene.addItem(logo);
    QSequentialAnimationGroup group;
    QPropertyAnimation animation_scale(logo, "scale");
    animation_scale.setDuration(1000);
    animation_scale.setStartValue(2.0);
    animation_scale.setEndValue(0.1);
    QPropertyAnimation animation_pos(logo, "pos");
    animation_pos.setDuration(1000);
    animation_pos.setStartValue(QPointF(0, 0));
    animation_pos.setEndValue(QPointF(100, 100));
    /**
    * it must indicate the center of rotation,
    * in this case it will be the center of the item
    */
    logo->setTransformOriginPoint(logo->boundingRect().center());
    QPropertyAnimation animation_rotate(logo, "rotation");
    animation_rotate.setDuration(1000);
    animation_rotate.setStartValue(0);
    animation_rotate.setEndValue(360);
    group.addAnimation(&animation_scale);
    group.addAnimation(&animation_pos);
    group.addAnimation(&animation_rotate);
    group.start();
    return a.exec();
}
#include "main.moc"

在下面的链接中有一个示例

或者你可以使用 QVariantAnimation 而不是 QPropertyAnimation:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsView w;
    QGraphicsScene scene(0, 0, 640, 480);
    w.setScene(&scene);
    w.show();
    QGraphicsPixmapItem* logo = new QGraphicsPixmapItem(QPixmap(":/image.jpg"));
    scene.addItem(logo);
    QSequentialAnimationGroup group;
    QVariantAnimation animation_scale;
    animation_scale.setDuration(1000);
    animation_scale.setStartValue(2.0);
    animation_scale.setEndValue(0.5);
    QObject::connect(&animation_scale, &QVariantAnimation::valueChanged, [logo](const QVariant &value){
        logo->setScale(value.toReal());
    });
    animation_scale.start();
    QVariantAnimation animation_pos;
    animation_pos.setDuration(1000);
    animation_pos.setStartValue(QPointF(0, 0));
    animation_pos.setEndValue(QPointF(100, 100));
    QObject::connect(&animation_pos, &QVariantAnimation::valueChanged, [logo](const QVariant &value){
        logo->setPos(value.toPointF());
    });
    /**
    * it must indicate the center of rotation,
    * in this case it will be the center of the item
    */
    logo->setTransformOriginPoint(logo->boundingRect().center());
    QVariantAnimation animation_rotate;
    animation_rotate.setDuration(1000);
    animation_rotate.setStartValue(0);
    animation_rotate.setEndValue(360);
    QObject::connect(&animation_rotate, &QVariantAnimation::valueChanged, [logo](const QVariant &value){
        logo->setRotation(value.toReal());
    });
    group.addAnimation(&animation_scale);
    group.addAnimation(&animation_pos);
    group.addAnimation(&animation_rotate);
    group.start();
    return a.exec();
}

在下面的链接中有一个示例