QPainterPath can contain many different kind of shapes and we can draw all those shape using drawPath API of QPainter. But I used it to animate an object on curve path instead of just drawing, QPainterPath has some intresting API using which curve animation is quite easy.
In my sample app, I want to animate dot on curve as shown in below pic.
To achieve this, I first created a curved QPainterPath like following,
QPainterPath path; path.moveTo(100,100); path.quadTo(100,600,400,400);Above code will draw curve as shown in above pic.
Now I created a timer and on timeout event, I am updating progress of dot on curve painter path. Like below.
void timeout() { progress += 0.01; if( progress > 1 ) { progress = 0; } update(); }Now that, I have progress of dot on curve path at certain point in terms of percentage.QPainterPath has API pointAtPercent(), that can be used to get point on curve path at progress value and can draw Dot object at that point like below.
void Testwidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawPath( path ); painter.setBrush(Qt::SolidPattern); painter.drawEllipse(path.pointAtPercent(progress),20,20); }Output of above code will look like following.
If you don't like creating animation using QTimer and wants same output using Qt's animation framework then following code shows how that can be done.
In following code, I have created a custom widget named DotWidget and I am animating it on curve path using QPropertyAnimation.
Following code creates a painter path and a widget then applies QPropertyAnimation on it.
createPath(); DotWidget* dotWidget = new DotWidget(this); QPropertyAnimation* animation = new QPropertyAnimation(dotWidget, "geometry",this); animation->setDuration(20000); animation->setEasingCurve(QEasingCurve::Linear); animation->setLoopCount(-1); //loop forever //setting value for animation on different position using QPainterPath for( double i = 0 ; i < 1; i = i+0.1) { animation->setKeyValueAt(i, QRect(path.pointAtPercent(i).toPoint(),QSize(30,30))); } animation->start();Following is code for DotWidget custom widget class. Its very simple widget that draws circle.
#includeI have created custom widget just to show how it can be done with custom widget, but you can apply same animation of any widget. I have uploaded video that shows output with QPushButton at end of post.#include class DotWidget : public QWidget { Q_OBJECT public: explicit DotWidget(QWidget *parent = 0) :QWidget(parent) {} void paintEvent(QPaintEvent *) { QPainter painter(this); painter.setBrush(Qt::SolidPattern); painter.drawEllipse(0,0,25,25); } };
Thats all,following is video for custom animation with timer.
Following is video for animation using QPropertyAnimation with QPushButton
Great !!
ReplyDeleteCan u please show how this path can be linked with any QML element ?
Ok I will create another post for QML
ReplyDelete