0

我正在尝试在 GraphicsScene 中做一些 3D 动画,例如,使用 Animation 框架旋转 GraphicsScene 中的图片(使用类,从qPixmapItem和子类QObject化,如果重要的话)。

一切正常,直到我想围绕垂直轴旋转图片。没有办法通过 item.rotate() 这样做,所以我正在使用QTranform.

问题是这样做根本不会为任何东西设置动画。我究竟做错了什么?

PS我不想为此使用OpenGL。

这是我的做法。这种方式适用于动画更简单的属性pos,如旋转(通过rotationsetRotation

我的代码:

// hybrid graphicsSceneItem, supporting animation 
class ScenePixmap : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
    Q_PROPERTY(QTransform transform READ transform WRITE setTransform)
public:
    ScenePixmap(const QPixmap &pixmap, QObject* parent = NULL, QGraphicsItem* parentItem = NULL):
        QObject(parent),
        QGraphicsPixmapItem(pixmap, parentItem)

    {}
};

这是我设置场景和动画的方法:

//setup scene
//Unrelated stuff, loading pictures, etc.
            scene = new QGraphicsScene(this);
        foreach(const QPixmap& image, images)
        {
            ScenePixmap* item = new ScenePixmap(image);
            item->moveBy(70*i, 0);
            i++;
            this->images.append(item);
            scene->addItem(item);
        }
    }

    ui->graphicsView->setBackgroundBrush(QBrush(Qt::black, Qt::SolidPattern));
    ui->graphicsView->setScene(scene);

    //setup animation
QTransform getTransform()
{
    QTransform transform;
    transform.rotate(-30, Qt::ZAxis);//also tried transform = transform.rotate(...)

    return transform;
}

QAbstractAnimation* SetupRotationAnimation(ScenePixmap* pixmapItem)
{
    QPropertyAnimation* animation = new QPropertyAnimation(pixmapItem, "transform");
    animation->setDuration(1400);
    animation->setStartValue( pixmapItem->transform());
    animation->setEndValue(getTransform());//here i tried to multiply with default transform , this does not work either
    return animation;
}

这是我开始动画的方式:

void MainWindow::keyPressEvent ( QKeyEvent * event )
{

    if((event->modifiers() & Qt::ControlModifier))
    {
        QAnimationGroup* groupAnimation = new QParallelAnimationGroup();


        foreach(ScenePixmap* image, images)
        {
            groupAnimation->addAnimation( SetupRotationAnimation(image));

        }

        groupAnimation->start(QAbstractAnimation::DeleteWhenStopped);

    }
}

编辑[已解决] 感谢 Darko Maksimovic:

这是为我解决的代码:

QGraphicsRotation* getGraphicRotation()
{
    QGraphicsRotation* transform = new QGraphicsRotation(this);

    transform->setAxis(Qt::YAxis);

    return transform;
}

QAbstractAnimation* SetupRotationAnimation(ScenePixmap* pixmapItem)
{
    QGraphicsRotation* rotation = getGraphicRotation();

    QPropertyAnimation* animation = new QPropertyAnimation(rotation, "angle");
    animation->setDuration(1400);
    animation->setStartValue( 0);
    animation->setEndValue(45);

    pixmapItem->setTransformOriginPoint(pixmapItem->boundingRect().center());

    QList<QGraphicsTransform*> transfromations = pixmapItem->transformations();
    transfromations.append(rotation);
    pixmapItem->setTransformations(transfromations);

    return animation;
}
4

2 回答 2

2

我看到你使用 QTransform。如果你只想要一个旋转,也就是简单的旋转,你最好使用setRotation [不要忘记setTransformOriginPoint ]。

但是,如果您想记住许多旋转,例如围绕不同的变换点,那么您应该使用QGraphicsTransform,即它的专用派生类QGraphicsRotation,您可以通过在图形对象上调用setTransformations来应用它(您应该首先获取现有的变换通过调用 o.transformations(),追加到 this,然后调用 setTransformations;如果您保留指向添加的转换的指针,您也可以稍后直接更改它)。

从您发布的代码中,我看不出您的错误来自哪里,但是通过使用专门的功能,您可以避免一些常见问题。

PS我还看到您在发布的代码中没有使用prepareGeometryChange,因此请注意,在转换对象时这是必要的。

于 2012-05-14T14:31:58.843 回答
0

问题很简单。QVariantAnimation并且QPropertyAnimation不支持QTransform。哎呀,他们现在甚至不支持无符号整数。这就是它的全部。根据 Qt 文档:

如果您需要对其他变体类型(包括自定义类型)进行插值,则必须自己为这些类型实现插值。为此,您可以为给定类型注册一个插值器函数。该函数接受 3 个参数:开始值、结束值和当前进度。

生成这样一个插值器可能不是那么简单。请记住,您必须在两个矩阵之间“混合”,同时保持矩阵的正交性和视觉效果。您需要将矩阵分解为单独的沿轴旋转、缩放、倾斜等子矩阵,然后分别对它们中的每一个进行插值。难怪 Qt 的人不这样做。做逆问题可能要容易得多:通过组合必要的旋转、平移等,生成所需的变换矩阵作为某个参数t的函数,所有这些都作为t的(可能是常数)函数给出。

仅仅因为 aQVariant可以携带一个类型并不意味着它受到默认插值器的支持。可能应该为此发出运行时警告。

于 2013-08-30T21:20:15.313 回答