如何在Qt中设置围绕固定点的线的动画



我试图在Qt中围绕一个固定点设置一条线的动画。我想我需要使用QPropertyAnimation类来实现这一点,但无法确定要使用哪个属性。

为了清楚起见,以下是我要做的。

|        (5, 10)
|       /
|      /
|     /
|    /          (10, 5)   
|   /          .
|  /
| /           
|/
|--------------------------
^
|---(0,0)

给定(x1,y1(=(0,0(&(x2,y2(=(5,10(,这将是动画的第一帧。然后,我想做一个从(x1,y1(,(x2,y2((其中(x1,y1(是线的一端,(x2、y2(是另一端(到(x1,y2,(x3,y3(的平滑动画,其中(x3、y3(=(10,5(。类似于钟表指针的动画设置方式。在有人发布模拟时钟示例之前,它使用了一个旋转的pixmap,这不是我所需要的。

我还没有找到很多关于Qt动画的信息,只有很多基本的GUI教程。

我试过做以下

QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry")

这种方法的问题是,在这种技术中,小部件使用->setStartValue(startX,startY,…(在基于小部件的(0,0(的2个点之间移动,并且不允许我将其中一行保持在固定点。

QPropertyAnimation *anim = new QPropertyAnimation(widget, "rotation")

这种方法的问题类似于几何体,它沿着(0,0(点旋转所述小部件。

有人能告诉我如何达到预期的效果吗?

谢谢。

QGraphicsXXXItem不支持q-属性,因此它们不能直接与QPropertyAnimation一起使用。因此,解决方案是创建一个继承QObjectQGraphicsLineItem的类,此外,我们必须添加一个q属性来处理与该行关联的QLineFp2位置,如下所示:

行项目.h

#ifndef LINEITEM_H
#define LINEITEM_H
#include <QGraphicsLineItem>
#include <QObject>
class LineItem: public QObject, public QGraphicsLineItem {
Q_OBJECT
Q_PROPERTY(QPointF p1 READ p1 WRITE setP1)
Q_PROPERTY(QPointF p2 READ p2 WRITE setP2)
public:
using QGraphicsLineItem::QGraphicsLineItem;
QPointF p1() const {
return  line().p1();
}
void setP1(const QPointF & p){
QLineF l = line();
l.setP1(p);
setLine(l);
}
QPointF p2() const {
return  line().p2();
}
void setP2(const QPointF & p){
QLineF l = line();
l.setP2(p);
setLine(l);
}
};
#endif // LINEITEM_H

main.cpp

#include "lineitem.h"
#include <QApplication>
#include <QGraphicsView>
#include <QPropertyAnimation>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene(-100, -100, 200, 200);
QGraphicsView view(&scene);
QGraphicsLineItem *item = scene.addLine(QLine(0, 100, 100, 0));
item->setPen(QPen(Qt::red, 5));
LineItem *lineItem = new LineItem(QLineF(QPointF(0, 0), QPointF(0, 100)));
scene.addItem(lineItem);
lineItem->setPen(QPen(Qt::green, 2));
QPropertyAnimation *anim = new QPropertyAnimation(lineItem, "p2");
anim->setStartValue(QPointF(0, 100));
anim->setEndValue(QPointF(100, 0));
anim->setDuration(2000);
anim->start();
view.resize(640, 480);
view.show();
return a.exec();
}

另一种方法是使用QVariantAnimation:

#include <QApplication>
#include <QGraphicsView>
#include <QPropertyAnimation>
#include <QGraphicsLineItem>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene(-100, -100, 200, 200);
QGraphicsView view(&scene);
scene.addLine(QLine(0, 100, 100, 0), QPen(Qt::green));
QGraphicsLineItem *item = scene.addLine(QLine(0, 0, 0, 100));
item->setPen(QPen(Qt::red, 5));
QVariantAnimation * anim = new QVariantAnimation(&scene);
anim->setStartValue(QPointF(0, 100));
anim->setEndValue(QPointF(100, 0));
anim->setDuration(2000);
anim->start();
QObject::connect(anim, &QVariantAnimation::valueChanged, [item](const QVariant & val){
QLineF l = item->line();
l.setP2(val.toPointF());
item->setLine(l);
});
view.resize(640, 480);
view.show();
return a.exec();
}

最新更新