采用QPainter绘图时需要在绘图设备的paintEvent()事件里编写绘图程序,实现整个绘图过程。此种方法绘制的图形时位图,适合于绘制复杂度不高的固定图形,不能实现图件的选择、编辑、拖放、修改等功能。
基类 | QPaintDevice(绘图设备,可以理解成“画板”’) |
派生类 | QGLFramebufferObject, QGLPixelBuffer, QImage, QOpenGLPaintDevice, QPagedPaintDevice, QPaintDeviceWindow, QPicture, QPixmap, QSvgGenerator, and QWidget |
一、 在上一篇文章的基础上,采用QPainter提供的功能,绘制一个五角星实例。
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反走样
painter.setRenderHint(QPainter::TextAntialiasing); // 反走样
// 生成五角星的5个顶点的,假设原点在五角星中心
qreal R=100; //半径
const qreal Pi=3.14159;
qreal deg=Pi*72/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))
};
// 设置字体
QFont font;
font.setPointSize(12);
font.setBold(true);
painter.setFont(font);
//设置画笔
QPen penLine;
penLine.setWidth(1); //线宽
penLine.setColor(Qt::red); //划线颜色
penLine.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
penLine.setCapStyle(Qt::FlatCap);//线端点样式
penLine.setJoinStyle(Qt::BevelJoin);//线的连接点样式
painter.setPen(penLine);
//设置画刷
QBrush brush;
brush.setColor(Qt::gray); //画刷颜色
brush.setStyle(Qt::DiagCrossPattern); //画刷填充样式
painter.setBrush(brush);
//设计绘制五角星的PainterPath,以便重复使用
QPainterPath starPath;
starPath.moveTo(points[0]);
starPath.lineTo(points[2]);
starPath.lineTo(points[4]);
starPath.lineTo(points[1]);
starPath.lineTo(points[3]);
// 闭合路径,最后一个点与第一个点相连
starPath.closeSubpath();
starPath.addText(points[0],font,"0"); //显示端点编号
starPath.addText(points[1],font,"1");
starPath.addText(points[2],font,"2");
starPath.addText(points[3],font,"3");
starPath.addText(points[4],font,"4");
//绘图
painter.save(); //保存坐标状态
painter.translate(100,200);
painter.drawPath(starPath); //画星星
painter.drawText(0,0,"S1");
painter.restore(); //恢复坐标状态
painter.translate(300, 200); //平移
painter.scale(0.8,0.8); //缩放
painter.rotate(90); //顺时针旋转
painter.drawPath(starPath);//画星星
painter.drawText(0,0,"S2");
painter.resetTransform(); //复位所有坐标变换
painter.translate(500, 200); //平移
painter.rotate(-145); //逆时针旋转
painter.drawPath(starPath);//画星星
painter.drawText(0,0,"S3");
}
在五角星绘制时,用到了QPainterPath类,使用该类可以绘制较为复杂的图形。
QPainterPath类提供的方法closeSubpath()可以闭合路径,即最后一个点与第一个点相连。
QPainter类提供的save()方法可以保存当前坐标状态,restore()方法恢复上一次的坐标状态。在使用过程中可以多次save()和restore()。
QPainter类提供的resetTransform()方法复位所有坐标变换,回到原始坐标状态。
二、 更改视口矩形区域,同时设定窗口范围,采用渐变色绘制图形。
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
//设置画笔
QPen pen;
pen.setWidthF(1); //线宽
pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
pen.setCapStyle(Qt::FlatCap);//线端点样式
pen.setJoinStyle(Qt::BevelJoin);//线的连接点样式
pen.setColor(Qt::gray); //划线颜色
painter.setPen(pen);
painter.drawLine(QPoint(0, 0), QPoint(2000, 0));
painter.setRenderHint(QPainter::Antialiasing);
pen.setColor(Qt::red); //划线颜色
painter.setPen(pen);
int W = width();
int H = height();
int side = qMin(W, H);//去长和宽的小值
// viewport矩形区
QRect rect((W - side) / 2, (H - side) / 2 , side, side);
painter.drawRect(rect); // 在原有坐标系下,绘制出Viewport区域
painter.setViewport(rect);//设置Viewport
painter.setWindow(-100, -100, 200, 200); // 设置窗口范围,逻辑坐标
线性渐变
QLinearGradient linearGrad(0,0,100,0);//从左到右,
linearGrad.setColorAt(0,Qt::yellow);//起点颜色
linearGrad.setColorAt(1,Qt::green);//终点颜色
linearGrad.setSpread(QGradient::PadSpread); //展布模式
painter.setBrush(linearGrad);
painter.setCompositionMode(QPainter::CompositionMode_Difference);
int ncount = 36;
for (int i = 0; i < ncount; i++)
{
painter.drawEllipse(QPoint(50, 0), 50, 50);
painter.rotate(10);
}
}
在上面的例子中,对单个圆使用线性渐变填充,共绘制了36个圆。采用setCompositionMode()方法进行叠加模式。叠加模式仅有40种枚举值,表示了后绘制图形与前面绘制图形的不同叠加运算方式。