首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >沿QPainterPath设置椭圆动画

沿QPainterPath设置椭圆动画
EN

Stack Overflow用户
提问于 2019-03-02 02:24:57
回答 1查看 144关注 0票数 0

我有一堆椭圆,它们最初排在路径的顶部,应该沿着QPainterPath移动。我让它在第一个椭圆上工作,但我不知道如何得到其他椭圆的正确位置。

有没有一种方法可以检查它是否通过了路径的末端并将其移回起点?

代码语言:javascript
复制
class Animation : public QAbstractAnimation
{
  public:
    Animation(const QPainterPath& path, QObject *parent = Q_NULLPTR);
    virtual void updateCurrentTime(int ms) override;
    virtual int duration() const override;
    QPainterPath mPath;
    QVector<EllipseGraphicsItem*> mAnimationElements;
};


Animation::Animation (const QPainterPath& path, QObject *parent) : QAbstractAnimation(parent)
, mPath(path)
{
    qreal pos = 0;
    qreal length = mPath.length();
    while (pos < length)
    {
        qreal percent = path.percentAtLength(pos);
        QPointF pointAtPercent = path.pointAtPercent(percent);
        pos += 40;
        EllipseGraphicsItem * item = new EllipseGraphicsItem(parentItem());
        mAnimationElements.append(item);
        item->setPos(pointAtPercent);
    }
}

void Animation::updateCurrentTime(int ms)
{
     QPointF point = mPath.pointAtPercent(qreal(ms) / 6000);

     if (mAnimationElements.size() > 0)
          mAnimationElements[0]->setPos(point);

     for (int i = 0; i < mAnimationElements.size(); i++) {
         // how to update each circle's position?
     }
}

开始动画:

代码语言:javascript
复制
QPainterPath path;
path.moveTo(10, 10);
path.lineTo(QPointF(500, 10));
path.lineTo(QPointF(500, 700));
path.lineTo(QPointF(10, 700));
Animation *animation = new Animation(path, this);
animation->setLoopCount(-1);
animation->start();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-02 03:19:09

Imho,使用带有QPropertyAnimationQGraphicsObject会更容易

使用在0和路径长度之间变化的属性,并通过根据元素的值及其在列表中的位置来计算元素的位置来放置元素。

一个简单的例子:

代码语言:javascript
复制
class AnimatedEllipses: public QGraphicsObject
{
    Q_OBJECT
    Q_PROPERTY(int progress READ progress WRITE setProgress)
private:
    QGraphicsPathItem path;
    QList<QGraphicsEllipseItem*> ellipses;
    int propProgress;
public:
    int progress() const { return propProgress;}
    void setProgress(int value)
    {
        propProgress = value;
        int index = 0;
        for (QGraphicsEllipseItem* ellipse: ellipses)
        {
            // Keep value between 0 and length.
            int lgt = (propProgress + index * 40) % int(path.path().length());
            qreal percent = path.path().percentAtLength(lgt);
            ++index;
            ellipse->setPos(path.path().pointAtPercent(percent));
        }
    }
    AnimatedEllipses(QPainterPath const& path): QGraphicsObject(), path(path), propProgress(0)
    {
        qreal pos = 0;
        qreal length = path.length();
        while (pos < length)
        {
            qreal percent = path.percentAtLength(pos);
            QPointF pointAtPercent = path.pointAtPercent(percent);
            pos += 40;
            QGraphicsEllipseItem * item = new QGraphicsEllipseItem(-10, -10, 20, 20, this);
            item->setPos(pointAtPercent);
            ellipses << item;
        }

        QPropertyAnimation* animation = new QPropertyAnimation(this, "progress");
        animation->setStartValue(0);
        animation->setEndValue(length);
        animation->setDuration(10000);
        animation->setLoopCount(-1);
        animation->start();
    }



    // QGraphicsItem interface
public:
    QRectF boundingRect() const { return path.boundingRect();}
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget){}
};

模使您可以为每个椭圆创建一个无限循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54950290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档