[英]Qt animate ellipses along the circle
我是Qt的新手,我很困惑如何使用QGraphicsScene
。 如果我將10個橢圓添加到場景中並沿路徑設置動畫,我該怎么做? 它變得更加復雜,因為如果我沿着橢圓繪制了10個橢圓,我想要為這些橢圓設置動畫,使它們遠離它們所在的橢圓的中心。 在圖片中,您可以看到省略號。 那些用QPainter
繪制我還沒弄明白如何將它們添加到場景中,但我希望灰色橢圓在內圈和外圈之間移動。 我已經通過了一些例子,但不能真正適應我的情況。
用於使用QPainter繪制省略號的代碼:
QPainter drElps;
drElps.setBrush(QBrush(QColor(0xaf, 0xaf, 0xaa)));
drElps.setPen(QPen(QColor(0xaf, 0xaf, 0xaa), 2));
double nrElps = 30;
int degree = (int)(360./nrElps);
painter.translate(QPointF(big_elps_circle_center));
while(--nrElps){
painter.drawEllipse(0, -60, 3, 3);
painter.rotate(degree);
}
painter.translate(QPOintF(back_to_origin));
如果你用QPainter繪制它們,那么你就在你的身上。 QGraphivsScene的要點是從QGraphicsItem繼承,繪制你需要在paintEvent上繪制的內容,將它們添加到場景中。
你在paintEvent上繪制了超過1個項目 - 所以你是獨立的 - 而且QGraphivsScene無法幫助你。
現在,如何正確地做到這一點:
在移動槽上,對橢圓的位置進行計算並移動(x,y)它。
您可以使用自定義圖形項, QGraphicsScene::advance
機制以及QTimeLine
來控制動畫。
大綱是這樣的:
QGraphicsScene *sc = new QGraphicsScene;
QTimeLine *tl = new QTimeLine(1000);
tl->setFrameRange(-20, 20);
connect(tl, &QTimeLine::frameChanged, sc, &QGraphicsScene::advance);
connect(tl, &QTimeLine::finished, tl, &QTimeLine::toggleDirection);
connect(tl, &QTimeLine::finished, tl, &QTimeLine::start);
for (int i = 0; i < 30; ++i) {
sc->addItem(new AnimItem(360./30*i, tl));
}
在自定義AnimItem中,您實現繪圖/動畫邏輯。 一個很好的基礎是QGraphicsEllipseItem
。 例如:
AnimItem::AnimItem(qreal angle, QTimeLine *timer, QGraphicsItem *parent)
: QGraphicsEllipseItem(0, 0, 3, 3, parent),
m_timer(timer)
{
QTransform t;
t.rotate(angle);
t.translate(0, -120);
setTransform(t);
setBrush(QBrush(QColor(0xaf, 0xaf, 0xaa)));
}
void AnimItem::advance(int phase)
{
if (phase == 1) {
QTransform t = transform();
t.translate(0, m_timer->currentFrame()/5);
setTransform(t);
}
}
Qt有一組面向動畫的類,為此你必須首先創建一個繼承自QGraphicsObject
的對象,在這個類中你必須實現方法paint
和boundingRect
。
ellipseobject.h
#ifndef ELLIPSEOBJECT_H
#define ELLIPSEOBJECT_H
#include <QGraphicsObject>
class EllipseObject : public QGraphicsObject
{
Q_OBJECT
public:
EllipseObject(QGraphicsItem * parent = 0);
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);
QRectF boundingRect() const;
};
#endif // ELLIPSEOBJECT_H
ellipseobject.cpp
#include "ellipseobject.h"
#include <QPainter>
EllipseObject::EllipseObject(QGraphicsItem *parent):QGraphicsObject(parent)
{
}
void EllipseObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(QColor(0xaf, 0xaf, 0xaa));
painter->setBrush(QBrush(QColor(0xaf, 0xaf, 0xaa)));
QRectF rect = boundingRect();
painter->drawEllipse(rect);
}
QRectF EllipseObject::boundingRect() const
{
return QRectF(-4, -4, 8, 8);
}
然后我們可以使用QPropertyAnimation
類,我們將為該位置設置動畫。
EllipseObject *item = new EllipseObject;
QPropertyAnimation *animation = new QPropertyAnimation(item, "pos");
for(int j = 0; j < p; j++){
animation->setKeyValueAt( 1.0*j/(p-1),
(r+ delta*sin(2*M_PI*j/p) )*QPointF(qSin(2*M_PI*i/number_of_items), qCos(2*M_PI*i/number_of_items)));
}
animation->setDuration(2000);
由於我們有幾個並行動畫的元素,我們可以使用QParallelAnimationGroup
來處理每個動畫。
group = new QParallelAnimationGroup(this);
[...]
group->addAnimation(animation);
如果我們想要連續,我們可以制作以下代碼。
group->start();
connect(group, &QParallelAnimationGroup::finished,[=](){
group->start();
});
完整的代碼在這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.