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
}