函数drawPath()绘制的是一个复合的图形,它使用一个QPainterPath类型的参数作为绘图的对象,QPainterPath类用于记录绘图的操作顺序,优点是绘制复杂图形时只需要创建一个painterpath,然后重复调用就可以了
在使用QPainterPath把路径画好之后,我们需要使用QPainter的drawPath把路径画上去才行!
void drawPath(const QPainterPath &path);
构造函数
QPainterPath(const QPointF &startPoint);
构造一个以startPoint为起点的对象,就是指定任意点为原点,不再使用左上角为原点!
等效于下面语句
QPainterPath startPath;
startPath.moveTo(points[0]);//设置当前点为(0,0)原点
void QPainterPath::moveTo(const QPointF &point)
将当前原点移动到指定点,隐式地开始一个新的子路径并关闭前一个。
void QPainterPath::lineTo(const QPointF &endPoint)
void QPainterPath::closeSubpath()
通过绘制一条线关闭当前子路径到子路径的开始(简称:首尾相连)
添加一条从当前位置到给定端点的直线。绘制线条后,当前位置将更新为线条的终点。
void QPainterPath::arcTo(const QRectF &rectangle, qreal startAngle, qreal sweepLength)
创建一个占用给定矩形的圆弧,从指定的startAngle开始,并逆时针扩展sweplength度。
void QPainterPath::cubicTo(const QPointF &c1, const QPointF &c2, const QPointF &endPoint)
使用由c1和c2指定的控制点在当前位置和给定端点之间添加三次贝塞尔曲线。添加曲线后,当前位置更新为曲线的终点。
坐标变换
视口:实际大小,以窗口左上角为原点的坐标
窗口:窗口坐标的中心定义在矩形的中心
平移
void QPainter::translate(qreal dx, qreal dy)
将坐标系在水平方向上平移dx单位,在垂直方向上平移dy单位 ,单位是像素
旋转
void QPainter::rotate(qreal angle)
坐标原点旋转angle角度,单位是度,为负数代表逆时针旋转
例子:translate(150,100)
rotate(90)
缩放
void QPainter::scale(qreal sx, qreal sy)
大于一表示放大,小于一表示缩小
坐标状态的保存于恢复
我们可以使用save()函数保存当前的坐标状态,用restore()恢复上次保存的坐标状态。这两个函数需要成对使用,因为他们操作的是一个栈!用resetTransform()则会复位所有的坐标变换,恢复成原始的坐标系!
案例
定义一个QPainterPath记录绘制一个五角星的过程,然后通过移动坐标原点,再进行缩放和旋转,绘制三个五角星
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);//图片抗锯齿
painter.setRenderHint(QPainter::TextAntialiasing);//文字抗锯齿
//设置字体
QFont font;
font.setPixelSize(14);//设置字体大小
painter.setFont(font);
//设置画笔
QPen penLine;
penLine.setWidth(2);//设置线条粗细
penLine.setColor(Qt::blue);
penLine.setStyle(Qt::SolidLine);//实线
penLine.setCapStyle(Qt::FlatCap);
penLine.setJoinStyle(Qt::BevelJoin);
painter.setPen(penLine);
//设置笔刷
QBrush brush;
brush.setColor(Qt::yellow);//黄色填充
brush.setStyle(Qt::SolidPattern);//笔刷填充样式
painter.setBrush(brush);
//五角星
qreal R = 100;//半径
const qreal Pi = 3.1415926;
qreal deg = Pi*(360/5)/180;//角度,(360/5)/180是弧度值
QPoint points[5]={
QPoint(R,0),
QPoint(R*qCos(deg),-R*qSin(deg)),
QPoint(R*qCos(2*deg),-R*qSin(2*deg)),
QPoint(R*qCos(3*deg),-R*qSin(3*deg)),
QPoint(R*qCos(4*deg),-R*qSin(4*deg)),
};
QPainterPath startPath;
startPath.moveTo(points[0]);//设置当前点为(0,0)原点
startPath.lineTo(points[2]);
startPath.lineTo(points[4]);
startPath.lineTo(points[1]);
startPath.lineTo(points[3]);
startPath.closeSubpath();//首尾相连,闭合路径
startPath.closeSubpath();
startPath.addText(points[0],font,"0");//显示顶点编号
startPath.addText(points[1],font,"1");
startPath.addText(points[2],font,"2");
startPath.addText(points[3],font,"3");
startPath.addText(points[4],font,"4");
//绘制第一个五角星
painter.save();//保存当前坐标原点
painter.translate(100,120);
painter.drawPath(startPath);//绘制五角星
painter.drawText(0,0,"S1");
painter.restore();//恢复坐标状态
//绘制第二个五角星
painter.translate(300,120);//平移
painter.scale(0.8,0.8);//缩放
painter.rotate(90);//顺时针旋转90度
painter.drawPath(startPath);//绘制五角星
painter.drawText(0,0,"S2");
//绘制第三个五角星
painter.resetTransform();//复位所有坐标变换
painter.translate(500,120);//平移
painter.scale(0.8,0.8);//缩放
painter.rotate(-145);//逆时针旋转145度
painter.drawPath(startPath);//绘制五角星
painter.drawText(0,0,"S3");
event->accept();
}