我有一个QGraphicsItem
我想为它设置大小变化的动画。因此,我需要随着时间的推移同时改变对象的height
和。width
我QTimeLine
过去曾将其用于单变量动画,如果可能的话,我想在这里将其用于双变量。但是,我没有看到QTimeLine::setFrameRange()
适用于两个变量的 a 。
我怎样才能做到这一点?有没有更好的 Qt 类呢?
我有一个QGraphicsItem
我想为它设置大小变化的动画。因此,我需要随着时间的推移同时改变对象的height
和。width
我QTimeLine
过去曾将其用于单变量动画,如果可能的话,我想在这里将其用于双变量。但是,我没有看到QTimeLine::setFrameRange()
适用于两个变量的 a 。
我怎样才能做到这一点?有没有更好的 Qt 类呢?
由于动画必须附加到对象,您的图形项将是 a QGraphicsObject
,因此您可以将相关属性公开给 Qt 属性系统。
由于您正在制作相当于 a 的动画QSizeF
,因此最简单的方法是将其公开为单个属性并使用 a QPropertyAnimation
。
通常,如果您必须并行设置多个属性的动画,请将它们设置为单独QPropertyAnimation
的 s。然后使用QParallelAnimationGroup
.
当然可以使用 a QTimeLine
,但是您必须手动在端点之间进行插值,例如基于帧号。何必。
下面是一个完整的示例,展示了如何同时为三个属性设置动画pos
:size
和rotation
。
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"