Search code examples
qtqgraphicsitem

Animation and custom property


I'm trying to animate graphics object in the code below. Both animations work if second one is uncommented. Also second (a2) animation works alone, but first animation (a1) doesn't work alone. Where is the problem?

// aitem.h
#ifndef AITEM_H
#define AITEM_H

#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsObject>
#include <QPainter>
#include <QPropertyAnimation>

class AItem : public QGraphicsObject
{
    Q_OBJECT
    Q_PROPERTY(qreal radius READ radius WRITE setRadius)

public:
    AItem(QGraphicsItem *parent = 0);
    ~AItem();

    qreal radius() const { return m_radius; }
    void setRadius (qreal r) { m_radius = r; }

    QRectF boundingRect () const;
    void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

private:
    QPropertyAnimation* a1;
    QPropertyAnimation* a2;
    qreal m_radius;

};

#endif // AITEM_H

// aitem.cpp
#include "aitem.h"

AItem::AItem(QGraphicsItem *parent): QGraphicsObject(parent), m_radius(10)
{
    a1 = new QPropertyAnimation (this, "radius");
    a1->setDuration(5000);
    a1->setStartValue(10);
    a1->setEndValue(150);
    a1->start();

    /*
    a2 = new QPropertyAnimation (this, "pos");
    a2->setDuration(5000);
    a2->setStartValue(QPointF(0, 0));
    a2->setEndValue(QPointF(300, 300));
    a2->start();
    */
}

AItem::~AItem()
{
}

QRectF AItem::boundingRect() const
{
    return QRectF (0, 0, m_radius, m_radius);
}

void AItem::paint(QPainter *painter, const QStyleOptionGraphicsItem     *option, QWidget *widget)
{
    painter->drawRect(0, 0, m_radius, m_radius);
}

Solution

  • When you say...

    first animation (a1) doesn't work alone

    what exactly do you mean? Do you mean that you've stepped through the code with a debugger and set_radius isn't called -- or simply that your AItem hasn't changed on screen? I suspect it's the latter in which case you need to add a call to QGraphicsItem::update in your set_radius implementation...

    void AItem::setRadius (qreal r)
    {
      m_radius = r;
      update();
    }
    

    Both animations work together because the second will invoke QGraphicsItem::setPos which will automatically trigger the required update.