QT QPainter 绘图

QT  QPainter 绘图

一、基本绘图类:

       Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。

  • QPainter 用于执行绘图操作,其提供的 API 在 GUI 或 QImage、QOpenGLPaintDevice、QWidget 和QPaintDevice 显示图形(线、形状、渐变等)、文本和图像。
  • QPaintDevice 不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到 QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture 等多种界面中间,必须使用 QPaintDevice。
  • QPaintEngine 提供了一些接口,可用于 QPainter 在不同的设备上进行绘制。

        绘图系统由 QPainter 完成具体的绘制操作,QPainter 类提供了大量高度优化的函数来完成 GUI 编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter 也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter 也支持线性变换,例如平移、旋转、缩放。

        QPainter 可以在继承自 QPaintDevice 类的任何对象上进行绘制操作。QPainter 也可以与 QPrinter 一起使用来打印文件和创建 PDF 文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。

       QPainter 一般在部件的绘图事件 paintEvent() 中进行绘制,首先创建 QPainter 对象,然后进行图形的绘制,最后记得销毁 QPainter 对象。当窗口程序需要升级或者重新绘制时,调用此成员函数。使用 repaint()和 update() 后,调用函数 paintEvent()。

绘图事件:

void wiget::paintEvent(QPaintEvent *event)
{ 
}

QPainter只能在paintEvent中进行绘图。paintEvent事件在窗口刷新时触发,如最大化最小化,拖动窗口边缘时也会触发。

主要属性:

(1) QPen:控制线条颜色宽度线性。

(2) QBrush:设置一个区域的填充特性。

(3) QFont:用于绘制文字。

(4) QPixmap: 绘制图片,适合小图片。

(5) QImage: 绘制图片,适合大图片。

(6) QBitmap: QPixmap的一个子类,单通道图

(7) QPicture: 一张画布,可以用于保存、读取Qpainter的绘图。

(8)QPrinter类是一个在打印机上绘制的绘图设备。它允许你将图形输出到打印机,生成打印预览,或者直接生成PDF文件。

基本图形绘制函数:

drawPoint() //画点

drawLine() //画直线

drawRect() //画矩形

drawArc() //画圆弧

drawEllipse() //画椭圆

drawPie() //画扇形

drawPolygon() //画多边形

drawChord() //画弦

drawRoundedRect() //画圆角矩形

drawPolyline() //画折线

drawConvexPolygon() //画凸多边形

二.重点绘图属性类介绍

1.QFont的一些属性与功能:

QFont是Qt框架中用于描述字体属性的工具类。

设置属性:

//设置属性:
void setFamily(const QString &family);

void setPointSize(int size);

void setWeight(int weight);

void setItalic(bool italic);

void setUnderline(bool underline);

获取属性:

//获取属性:
QString family() const;

int pointSize() const;

int weight() const;

bool italic() const;

bool underline() const;

2.QPen的一些属性与功能:

主要函数:

//函数原型 功能

void setColor(QColor &color) //设置画笔颜色

void setWidth(int width) //设置线条宽度

void setStyle(Qt::PenStyle style) //设置线条样式,参数为Qt::PenStyle枚举类型

void setCapStyle(Qt::PenCapStyle style) //设置线条端点样式,参数为Qt::PenCapStyle枚举类型

void setJoinStyle(Qt::PenJoinStyle style)//设置连接样式,参数为Qt::PenJoinStyle枚举类型属性修改后,需要使用setPen()来应用于绘图。
(1)线条样式:
void setStyle(Qt::PenStyle style) //设置线条样式,参数为Qt::PenStyle枚举类型

Qt::NoPen //没有画笔,设置此属性时,用画笔不会画出任何东西。但是画刷仍然有效,表现出来就是无边界,但有填充。

Qt::SolidLine //实线

Qt::DashLine //虚线

Qt::DotLine //点状线

Qt::DashDotLine //虚线和点交替

Qt::DashDotDotLine //虚线和双点交替

Qt::CustomDashLine //自定义样式

(2)线条端点样式:
void setCapStyle(Qt::PenCapStyle style) //设置线条端点样式,参数为Qt::PenCapStyle枚举类型
Qt::FlatCap //平顶端点

Qt::SquareCap //方形端点

Qt::RoundCap //圆形端点

(3)线条连接样式:
void setJoinStyle(Qt::PenJoinStyle style)//设置连接样式,参数为Qt::PenJoinStyle枚举类型属性修改后,需要使用setPen()来应用于绘图。

Qt::BevelJoin //斜切连接

Qt::MiterJoin //直角连接

Qt::RoundJoin //圆连接

3.QBrush的一些属性与功能:

主要函数:

//函数原型 功能

void setColor(QColor &color) //设置画刷颜色

void setStyle(Qt::BrushStyle style) //设置画刷样式

void setTexture(QPixmap &pixmap) //设置一个QPixmap图片作为画刷的图片

void setTextureImage(QImage &image) //设置一个QImage类型的图片作为画刷的图片

(1)基本填充和线性填充:

//枚举常量 描述

Qt::NoBrush //不填充

Qt::SolidPattern //单一颜色填充

Qt::HorPattern //水平线填充

Qt::VerPattern //垂直线填充

(2)渐变填充:

Qt::LinearGradientPattern //线性渐变,需要使用QLinearGradient类对象作为Brush

Qt::RadialGradientPattern //辐射渐变,需要使用QRadialGradient类对象作为Brush

Qt::ConicalGradientPattern //圆锥型渐变,需要使用QConicalGradient类对象作为Brush

Qt::TexturePattern //材质填充,需要指定texture或textureImage图片

4. QPrinter用法

(1)QPrinter printer;

printer.setOutputFormat(QPrinter::PdfFormat); // 设置输出格式为PDF,也可以其他格式

printer.setOutputFileName("output.pdf"); // 设置输出文件名

QPainter painter1(&printer);

painter1.drawText(100, 100, "Hello, PDF1!");

painter1.end(); // 结束绘制,内容将被发送到打印机

(2)注意:

用QPrinter需要添加 QT += printsupport;

当设置QPainter painter1(&printer)后,绘制图形输出到pdf文件,就不会再输出到ui页面上了。

sample8_123QPainter.h  文件

#pragma once

#include <QtWidgets/QWidget>
#include "ui_sample8_123QPainter.h"



class sample8_123QPainter : public QWidget
{
	Q_OBJECT

public:
	sample8_123QPainter(QWidget *parent = Q_NULLPTR);

private:
	Ui::sample8_123QPainterClass ui;


protected:
	void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;//Q_DECL_OVERRIDE 表示这个函数是对父类虚函数的重载

	void MyPaint1();//绘制矩形
	
	void MyPaintText();//绘制文本
	
	void MyPaintLine();//绘制直线
	
	void MyPaintArc();//绘制弧线
	
	void MyPaintEllipse();//绘制椭圆
	
	void MyPaintPloygon();//绘制多边形
	
	void MyPaintPicture();//绘制图片

	void MyQLinearGradient();//线性渐变

	void MyQRadialGradient();//径向渐变




};

sample8_123QPainter.cpp  文件

#include "sample8_123QPainter.h"

#include    <QPainter>


sample8_123QPainter::sample8_123QPainter(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	setPalette(QPalette(Qt::white));//设置窗口为白色背景
	setAutoFillBackground(true);
	this->resize(400, 400);
}

void sample8_123QPainter::paintEvent(QPaintEvent *event)
{
	//MyPaint1();//绘制矩形

	MyPaintText();//绘制文本

}

绘制文本:

//绘制文本
void sample8_123QPainter::MyPaintText()
{
	QPainter painter(this);
	// 设置画笔颜色
	painter.setPen(QColor(0, 160, 230));

	// 设置字体:微软雅黑、点大小50、斜体
	QFont font;
	font.setFamily("Microsoft YaHei");
	font.setPointSize(50);
	font.setItalic(true);
	painter.setFont(font);

	// 绘制文本
	painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

       创建一个 QPainter 对象,用于后面的绘制。使用 setPen() 来设置画笔的颜色(淡蓝色)。通过使用 QFont 来构建我们想要的字体,setFamily()设置字体为微软雅黑、setPointSize() 设置点大小30、setItalic() 设置斜体, 然后通过 setFont() 来设置字体,最后调用 drawText() 来实现文本的绘制,这里的 rect() 是指当前窗体的显示区域,Qt::AlignCenter 指文本居中绘制。

绘制矩形:

void sample8_123QPainter::MyPaint1()
{
	QPainter painter(this);//创建QPainter对象
	painter.setRenderHint(QPainter::Antialiasing);//
	painter.setRenderHint(QPainter::TextAntialiasing);//

	int W = this->width(); //绘图区宽度
	int H = this->height();//绘图区高度
	QRect rect(W / 4, H / 4, W / 2, H / 2);//中间区域矩形框

	//设置画笔
	QPen pen;
	pen.setWidth(3);//线宽
	pen.setColor(Qt::red);//划线颜色

	//Qt::NoPen,Qt::SolidLine, Qt::DashLine, Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine
	pen.setStyle(Qt::DashLine);//线的类型,实线、虚线等

	//Qt::FlatCap, Qt::SquareCap,Qt::RoundCap
	pen.setCapStyle(Qt::FlatCap);//线端点样式

	//Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin,Qt::SvgMiterJoin
	pen.setJoinStyle(Qt::BevelJoin);//线的连接点样式
	painter.setPen(pen);

	//设置画刷1
	QBrush  brush;
	brush.setColor(Qt::yellow); //画刷颜色
	brush.setStyle(Qt::SolidPattern); //画刷填充样式
	painter.setBrush(brush);

	设置画刷2
	//QPixmap texturePixmap("../sample8_1QPainter/images/texture.jpg");// 
	//QBrush  brush;
	//brush.setStyle(Qt::TexturePattern);//画刷填充样式
	//brush.setTexture(texturePixmap);//设置材质图片
	//painter.setBrush(brush);

	//绘图
	//painter.drawLine(rect.left(),rect.top(),rect.right(),rect.bottom());
	//painter.drawRect(rect);//只填充定义的渐变区域
	//painter.drawRect(this->rect()); //填充更大区域,会有延展效果

	//painter.fillRect(rect,Qt::red);//只填充定义的渐变区域,用红色填充
	//painter.drawRoundRect(rect);//只填充定义的渐变区域,圆角矩形
	painter.drawRoundedRect(rect,40,20);
}

       使用 setPen() 来设置画笔颜色(淡蓝色)、宽度(2 像素),用来设置矩形区域的边框。然后使用setBrush() 来设置画刷颜色(橙色),用来填充矩形区域,最后调用 drawRect() 来实现矩形的绘制,其中参数依次顺序为 x、y、w、h,是指区域从 x 为 50,y 为 50 的坐标点起,宽度为 160,高度为 100 的矩形。

绘制直线:

//绘制直线
void sample8_123QPainter::MyPaintLine()
{
	QPainter painter(this);
	// 反走样
	painter.setRenderHint(QPainter::Antialiasing, true);
	// 设置画笔颜色
	painter.setPen(QColor(0, 160, 230));
	// 绘制直线
	painter.drawLine(QPointF(0, height()), QPointF(width() / 2, height() / 2));
}

       通过 setRenderHint() 来设置反走样,要么绘制出来的线条会出现锯齿,调用 setPen() 来设置画笔颜色(淡蓝色)。最后调用 drawLine() 来实现直线的绘制,其中 QPointF(0, height()) 是指直线的起点坐标、QPointF(width() / 2, height() / 2) 是指直线的终点坐标。

绘制弧线:

//绘制弧线
void sample8_123QPainter::MyPaintArc()
{
	//矩形
	QRectF rect(90.0, 90.0, 80.0, 90.0);
	//起始角度
	int startAngle = 30 * 16;
	//跨越度数
	int spanAngle = 120 * 16;

	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing, true);

	//设置画笔颜色、宽度
	painter.setPen(QPen(QColor(0, 160, 230), 2));

	//绘制弧线
	painter.drawArc(rect, startAngle, spanAngle);
}

       画弧线时,角度被分成了十六分之一,就是说,如果要 30 度,就需是 30*16。它有起始角度和跨度,还有位置矩形,所以,要想画出自己想要的弧线,就需要大概估算出各个参数的预估值。

绘制椭圆:

//绘制椭圆
void sample8_123QPainter::MyPaintEllipse()
{
	QPainter painter(this);

	//painter.setRenderHint(QPainter::Antialiasing, true);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setRenderHint(QPainter::TextAntialiasing);

	int W = this->width(); //绘图区宽度
	int H = this->height();//绘图区高度
	QRect rect(W / 4, H / 4, W / 2, H / 2);//中间区域矩形框

	//设置画笔颜色、宽度
	painter.setPen(QPen(QColor(0, 160, 230), 3));

	//绘制椭圆
	painter.drawEllipse(QPointF(120, 60), 50, 20);

	//设置画刷颜色
	painter.setBrush(QColor(255, 160, 90));

	//绘制圆
	painter.drawEllipse(QPointF(120, 140), 40, 40);

	//设置画刷颜色
	painter.setBrush(QColor(90, 160, 255));
	painter.drawEllipse(rect);
}

       绘制了一个椭圆和一个圆形,都是调用 drawEllipse() 接口,我们可以很轻易的发现,如果为椭圆的时候,后面两个参数不一样,圆形则相同。首先我们来看第一个参数 QPointF 是指椭圆的中心点相对当前窗体 QPoint(0, 0) 点的位置,后面的参数指椭圆的 x 轴及 y 轴的半径。

绘制多边形:

//绘制多边形
void sample8_123QPainter::MyPaintPloygon()
{
	QPainter painter(this);

	//反走样
	painter.setRenderHint(QPainter::Antialiasing, true);

	//设置画笔颜色
	//painter.setPen(QColor(0, 160, 230));
	//设置画笔颜色、宽度
	painter.setPen(QPen(QColor(0, 160, 230), 3));

	//各个点的坐标
	static const QPointF points[4] = { QPointF(30, 40), QPointF(60, 150), QPointF(150, 160), QPointF(220, 100) };

	//绘制多边形
	painter.drawPolygon(points, 4);
}

绘制图片:

//绘制图片
void sample8_123QPainter::MyPaintPicture()
{
	QPainter painter(this);

	//反走样
	painter.setRenderHint(QPainter::Antialiasing, true);

	// 绘制图标
	painter.drawPixmap(rect(), QPixmap("../sample8_1QPainter/images/001.jpg"));//
}

        通过 drawPixmap() 来绘制图片,我们可以指定图片绘制的区域 QRect,这里为整个界面的区域,当界面伸缩的时候,图片也会跟着伸缩。

渐变绘制:

1、线性渐变

//线性渐变
void sample8_123QPainter::MyQLinearGradient()
{
	QPainter    painter(this);//创建QPainter对象
	painter.setRenderHint(QPainter::Antialiasing);//
	painter.setRenderHint(QPainter::TextAntialiasing);//

	int W = this->width();//绘图区宽度
	int H = this->height();//绘图区高度
	QRect rect(W / 4, H / 4, W / 2, H / 2);//中间区域矩形框

	//线性渐变
	//QLinearGradient  linearGrad(rect.left(),rect.top(),rect.right(),rect.bottom()); //对角线
	QLinearGradient  linearGrad(rect.left(), rect.top(), rect.right(), rect.top());//从左到右
	linearGrad.setColorAt(0, Qt::blue);//起点颜色
	linearGrad.setColorAt(0.5, Qt::green);//起点颜色
	linearGrad.setColorAt(1, Qt::red);//终点颜色
	linearGrad.setSpread(QGradient::ReflectSpread);//展布模式
	//QGradient::PadSpread ,QGradient::RepeatSpread, QGradient::ReflectSpread
	painter.setBrush(linearGrad);

	//绘图
	painter.drawRect(rect);//只填充定义的渐变区域
	//painter.drawRect(this->rect());//填充更大区域,会有延展效果
}
    //绘图
	painter.drawRect(rect);//只填充定义的渐变区域
	//painter.drawRect(this->rect());//填充更大区域,会有延展效果

  

    //绘图
	//painter.drawRect(rect);//只填充定义的渐变区域
	painter.drawRect(this->rect());//填充更大区域,会有延展效果

  

2、径向渐变

//径向渐变
void sample8_123QPainter::MyQRadialGradient()
{
	QPainter    painter(this);//创建QPainter对象
	painter.setRenderHint(QPainter::Antialiasing);//
	painter.setRenderHint(QPainter::TextAntialiasing);//

	int W = this->width();//绘图区宽度
	int H = this->height();//绘图区高度
	QRect rect(W / 4, H / 4, W / 2, H / 2);//中间区域矩形框

	//径向渐变
	QRadialGradient  radialGrad(W / 2, H / 2, qMax(W / 8, H / 8), W / 2, H / 2);
    //radialGrad.setColorAt(0,Qt::white);
	radialGrad.setColorAt(0,Qt::green);
	radialGrad.setColorAt(1,Qt::blue);
	radialGrad.setSpread(QGradient::ReflectSpread);
	//QGradient::PadSpread ,QGradient::RepeatSpread, QGradient::ReflectSpread
	painter.setBrush(radialGrad);

	//绘图
	//painter.drawRect(rect);//只填充定义的渐变区域
	painter.drawRect(this->rect());//填充更大区域,会有延展效果
}

  

3、圆锥形渐变

//圆锥型渐变
void sample8_123QPainter::MyQConicalGradient()
{
	QPainter    painter(this);//创建QPainter对象
	painter.setRenderHint(QPainter::Antialiasing);//
	painter.setRenderHint(QPainter::TextAntialiasing);//

	int W = this->width();//绘图区宽度
	int H = this->height();//绘图区高度
	QRect rect(W / 4, H / 4, W / 2, H / 2);//中间区域矩形框

	//圆锥型渐变
	QConicalGradient  coniGrad(W/2,H/2,45);
	coniGrad.setColorAt(0,Qt::yellow);
	coniGrad.setColorAt(0.5,Qt::blue);
	coniGrad.setColorAt(1,Qt::green);
    //coniGrad.setSpread(QGradient::PadSpread);//对于锥形渐变不起作用
	painter.setBrush(coniGrad);

	//绘图
	painter.drawRect(rect);//只填充定义的渐变区域
	//painter.drawRect(this->rect());//填充更大区域,会有延展效果
}

  

《Qt5/6 C++开发指南》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值