void ComplicatedPathWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.lineTo(100, 0);
path.cubicTo(200, 0, 100, 50, 200, 100); // 贝塞尔曲线
path.closeSubpath(); // 画一条线到路径的第一个点,闭合路径
path.addRect(50, 50, 50, 50); // 加一个矩形
QPainterPath path2;
path2.addEllipse(80, 30, 50, 50);
path = path.subtracted(path2); // 扣掉圆
painter.translate(20, 20);
painter.setBrush(Qt::lightGray);
painter.drawPath(path);
painter.setBrush(Qt::NoBrush);
painter.drawRect(path.boundingRect());
}
QPainterPath::pointAtPercent(qreal t) 是一个很有用的函数,t 的值为 [0, 1.0],可以取得路径上任意一点的坐标,在动画一节里会使用这个函数来实现动画的插值函数,让物体沿着任意的路径运动,这里没有用 Qt 的动画框架实现了让物体沿着任意的路径运动
#ifndef ANIMATIONALONGPATHWIDGET_H
#define ANIMATIONALONGPATHWIDGET_H
#include
#include
class AnimationAlongPathWidget : public QWidget {
Q_OBJECT
public:
explicit AnimationAlongPathWidget(QWidget *parent = 0);
~AnimationAlongPathWidget();
protected:
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
QPainterPath path;
float percent;
float step;
int timerId;
};
#endif // ANIMATIONALONGPATHWIDGET_H
#include "AnimationAlongPathWidget.h"
#include
#include
#include
AnimationAlongPathWidget::AnimationAlongPathWidget(QWidget *parent) : QWidget(parent) {
step = 0.02;
percent = 0;
// 构造一个任意的曲线
path.cubicTo(50, 0, 30, 100, 100, 100);
path.cubicTo(150, 100, 250, 0, 200, 100);
path.cubicTo(150, 100, 250, 0, 300, 140);
path.quadTo(150, 310, 150, 100);
// 启动定时器
timerId = startTimer(60);
}
AnimationAlongPathWidget::~AnimationAlongPathWidget() {
}
void AnimationAlongPathWidget::timerEvent(QTimerEvent *event) {
// 不停的更新 percent 的值,刷新界面,实现动画效果
if (event->timerId() == timerId) {
percent += step;
if (percent < 0 || percent > 1) {
step = -step; // 运动方向取反
percent = qMin(percent, 1.0F);
percent = qMax(percent, 0.0F);
}
update();
}
}
void AnimationAlongPathWidget::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(20, 20);
painter.drawPath(path);
painter.setBrush(Qt::red);
painter.drawEllipse(path.pointAtPercent(percent), 4, 4);
}