QPainter二维绘图(三)

采用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种枚举值,表示了后绘制图形前面绘制图形的不同叠加运算方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值