Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 动态更改QProperty动画持续时间_Qt_Qpainterpath_Qpropertyanimation - Fatal编程技术网

Qt 动态更改QProperty动画持续时间

Qt 动态更改QProperty动画持续时间,qt,qpainterpath,qpropertyanimation,Qt,Qpainterpath,Qpropertyanimation,我正在使用该解决方案沿QPainterPath设置椭圆动画。 但我需要缓慢地增加或降低动画的速度。 我创建了一个计时器并为动画设置了一个新的持续时间,但结果是一个起伏的动画,因为椭圆从一开始就开始了。 有没有更好的方法来实现这一点 class AnimatedEllipses: public QGraphicsObject { Q_OBJECT Q_PROPERTY(int progress READ progress WRITE setProgress) private:

我正在使用该解决方案沿
QPainterPath
设置椭圆动画。 但我需要缓慢地增加或降低动画的速度。 我创建了一个计时器并为动画设置了一个新的持续时间,但结果是一个起伏的动画,因为椭圆从一开始就开始了。 有没有更好的方法来实现这一点

class AnimatedEllipses: public QGraphicsObject
{
    Q_OBJECT
    Q_PROPERTY(int progress READ progress WRITE setProgress)
private:
    QGraphicsPathItem path;
    QList<QGraphicsEllipseItem*> ellipses;
    int propProgress;
    QPropertyAnimation* animation;

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;
        }

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

        QTimer *timer = new QTimer();
        connect(timer, SIGNAL(timeout()), this, SLOT(SlotTimeOut()));
        timer->start(1000);
    }

    void SlotTimeOut() {
        int newDuration = GetRandomDuration();
        animation->setDuration(newDuration);
    }

    // QGraphicsItem interface
public:
    QRectF boundingRect() const { return path.boundingRect();}
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget){}
};
class animatedellipes:public QGraphicsObject
{
Q_对象
Q_属性(int progress READ progress WRITE setProgress)
私人:
qp路径;
QList椭圆;
国际进步;
QPropertyAnimation*动画;
公众:
int progress()常量{return propProgress;}
void setProgress(int值)
{
进步=价值;
int指数=0;
对于(QGraphicsEllipseItem*椭圆:椭圆)
{
//将值保持在0和长度之间。
int lgt=(propProgress+索引*40)%int(path.path().length());
qreal percent=path.path().percentAtLength(lgt);
++指数;
椭圆->设置位置(path.path().pointAtPercent(percent));
}
}
AnimatedAllipes(QPainterPath常量和路径):QGraphicsObject(),路径(路径),propProgress(0)
{
qreal pos=0;
qreal length=path.length();
while(pos设置位置(点百分比);
椭圆设置起始值(0);
动画->设置结束值(长度);
动画->设置持续时间(10000);
动画->设置循环计数(-1);
动画->开始();
QTimer*定时器=新的QTimer();
连接(计时器、信号(超时())、此、插槽(SlotTimeOut());
定时器->启动(1000);
}
void SlotTimeOut(){
int newDuration=GetRandomDuration();
动画->设置持续时间(新建持续时间);
}
//QSITEM接口
公众:
QRectF boundingRect()常量{返回路径.boundingRect();}
无效绘制(QPainter*painter,const QStyleOptionGraphicsItem*选项,QWidget*小部件){}
};

您可以使用自定义的
QEasingCurve
来实现这一点。下面是progressbar值的一个小示例

main window.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void OnChangeDurationTimer();

private:
    Ui::MainWindow *ui;
    QPropertyAnimation m_animProgress;
};
初始化

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_animProgress.setTargetObject(ui->progressBar);
    m_animProgress.setPropertyName("value");
    m_animProgress.setStartValue(0);
    m_animProgress.setEndValue(100);
    m_animProgress.setDuration(10000);
    m_animProgress.setLoopCount(-1);

    //setting custom QEasingCurve
    QEasingCurve eCurve;
    eCurve.setCustomType(myEasingFunction);
    m_animProgress.setEasingCurve(eCurve);

    m_animProgress.start();

    QTimer::singleShot(3000, this, &MainWindow::OnChangeDurationTimer);  //timer to change duration
}
最有趣的是自定义测量曲线的函数
myEasingFunction

qreal g_offset = 0;       //value last animation stopped with
qreal g_offsetLast = 0;   //keep current value of animation

qreal myEasingFunction(qreal progress)
{
    qreal val = g_offset + progress;
    while (val > 1) {
        val -= 1;  //normalize
    }
    g_offsetLast = val;
    return val;
}
以及更改计时器上的持续时间

void MainWindow::OnChangeDurationTimer()
{
    g_offset = g_offsetLast;  //remember stopped value
    m_animProgress.stop();
    m_animProgress.setDuration((rand() % 10 + 1) * 1000);
    m_animProgress.start();

    QTimer::singleShot(3000, this, &MainWindow::OnChangeDurationTimer);  //next changing
}