如何在 Qt 中围绕固定点设置动画?
How to animate line around fixed point in Qt?
我正在尝试在 Qt 中围绕一个固定点设置一条线的动画。我假设我需要使用 QPropertyAnimation
class 来执行此操作,但不知道要使用哪个 属性。
为清楚起见,这是我正在尝试做的事情。
| (5, 10)
| /
| /
| /
| / (10, 5)
| / .
| /
| /
|/
|--------------------------
^
|---(0,0)
给定 (x1, y1) = (0, 0) & (x2, y2) = (5, 10),这将是动画的第一帧。然后我想从 (x1, y1), (x2, y2), ((x1, y1) 是线的一端,(x2, y2) 是另一端)到 (x1 , y1), (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-properties,因此不能直接与 QPropertyAnimation
一起使用。所以解决方案是创建一个继承QObject
和QGraphicsLineItem
的class,另外我们必须添加一个q-属性来处理p2
的位置QLineF
关联的行如下图:
lineitem.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();
}
我正在尝试在 Qt 中围绕一个固定点设置一条线的动画。我假设我需要使用 QPropertyAnimation
class 来执行此操作,但不知道要使用哪个 属性。
为清楚起见,这是我正在尝试做的事情。
| (5, 10)
| /
| /
| /
| / (10, 5)
| / .
| /
| /
|/
|--------------------------
^
|---(0,0)
给定 (x1, y1) = (0, 0) & (x2, y2) = (5, 10),这将是动画的第一帧。然后我想从 (x1, y1), (x2, y2), ((x1, y1) 是线的一端,(x2, y2) 是另一端)到 (x1 , y1), (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-properties,因此不能直接与 QPropertyAnimation
一起使用。所以解决方案是创建一个继承QObject
和QGraphicsLineItem
的class,另外我们必须添加一个q-属性来处理p2
的位置QLineF
关联的行如下图:
lineitem.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();
}