QPainter提供了高度优化的功能来完成大多数绘图GUI程序所需要的工作。它可以画出一切,从简单的线条到复杂的形状。还可以绘制文本和像素图。QPainter可以对继承了QPaintDevice 的类的任何对象进行操作。
QPainter的常见用法是在控件的“绘图事件”paintEvent()中构造QPainter对象,和定制笔刷或画笔,然后开始绘画,绘画完成后记得要销毁QPainter对象。
在paintEvent()外部构造QPainter对象,程序运行时报错:
QWidget::paintEngine: Should no longer be called
有时导致闪退。
QPainter的核心功能是绘图,允许用户自定义QPainter的设置及其渲染质量,还可以通过指定QPainter对象的合成模式来控制不同的形状如何层叠在一起。
isActive() 函数指示画家是否处于活动状态。
begin() 函数和接受QPaintDevice 的构造函数激活画家。
end() 函数和析构函数停用它。
QPainter与 QPaintDevice和 QPaintEngine 一起,构成了Qt绘图系统的基础。
QPainter是用于执行图形操作的类。
QPaintDevice表示可以使用QPainter进行绘制的设备。
QPaintEngine提供了QPainter用来绘制不同类型设备的接口。
如果painter处于活动状态,device() 返回正在用于绘画的设备, paintEngine() 返回当前正在运行的 painter 引擎。(参见Paint System)
有时用户希望在特殊的QPaintDevice上作画,QPainter通过静态函数setRedirected() 来实现重定向。
警告:当绘画设备是一个控件时,只能在paintEvent() 函数内部或paintEvent() 调用的函数中使用QPainter。【跟前面说的一样,可以说是反复强调了】
设置
QPainter 有以下偏好设置:
font()
- 用于绘制文本的字体。如果画家 isActive(),则可以分别使用fontInfo() 和 fontMetrics()函数检索有关当前设置的字体及其度量的信息。
brush()
- 定义了用于填充形状的颜色或图案。
pen()
- 定义了用于绘制线或边界的颜色或点画。
- 定义了是否存在一个背景background() ,它有两种模式:不透明Qt::OpaqueMode 或透明 Qt::TransparentMode。
- 当背景模式不透明,并且 pen() 是一个“点画”的情况下,它描述了背景像素的颜色。
- 定义画刷的原点,通常是控件背景的原点。
viewport(), window(), worldTransform()
- 视口,窗口,世界坐标变换构成了画家的坐标变换系统。有关更多信息,请参见坐标变换部分和坐标系文档( Coordinate Transformations 和 Coordinate System )。
- 是否有剪切。
- 定义在绘制文本时使用的布局方向。
- 是否使用世界坐标。
- 是否使用视图转换。
用户可以随时调用save() 函数来保存QPainter的状态,该函数可以在一个内部堆栈上保存所有可用的设置。restore() 功能会将它们回调。
绘画
QPainter提供了最原始的绘制功能: drawPoint(), drawPoints(), drawLine(), drawRect(), drawRoundedRect(), drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(), drawPolygon(), drawConvexPolygon() 和 drawCubicBezier()。还有 drawRects() 和drawLines(),使用当前的笔和画刷在给定的QRects或QLines数组中绘制给定数量的矩形或线。
QPainter类还提供了填充fillRect()函数,它用给定的QRect,和给定的QBrush填充,以及使用eraseRect()函数删除给定矩形区域内的填充。
所有这些函数都有整数版本和浮点版本。
基本绘图样例:
如果你需要绘制一个复杂的形状,特别是如果你需要重复绘制,可以考虑创建QPainterPath,并使用绘制路径。
QPainter还提供了填充路径v函数,它用给定的QBrush填充给定的路径,以及绘制给定路径描边的strokePath() 函数。
下图向量变形Vector Deformation显示如何使用高级向量技术绘制文本; Gradients显示Qt的不同类型的渐变;Path Stroking显示Qt的内置的描边模式和显示如何使用自定义模式来扩展可用模式的范围。
文本绘制是使用 drawText() 来完成的。当您需要细粒度定位时,boundingRect() 告诉您给定的drawText() 命令将绘制在哪里。
绘制像素和图像
QPainter有绘制 pixmaps / images 的功能,即:绘制像素图 drawPixmap()、绘制图像 drawImage() 和绘制倾斜的像素图 drawTiledPixmap()。
drawPixmap() 和 drawImage() 产生相同的结果,drawPixmap()在屏幕上更快,而 drawImage() 在 QPrinter 或其他设备上更快。
drawPicture() 函数,它可以绘制整个QPicture的内容。drawPicture() 是唯一无视所有画家的设置,因为QPicture 有自己的设置。
绘制高分辨率像素图和图像
高分辨率版本的像素图的设备像素比大于1(参见QImageReader, QPixmap::devicePixelRatio())。如果它与底层QPaintDevice的值匹配,它将直接绘制到设备上,不应用额外的转换。
渲染质量
为了使用QPainter获得最佳的渲染结果,你应该使用平台独立的QImage作为渲染设备。使用QImage的将确保结果在任何平台上都具有相同的像素表示。
QPainter类还提供了一种通过其 RenderHint 枚举和支持浮点精度来控制渲染质量的方法,这些经常与 QPainter::Antialiasing抗锯齿渲染提示一起使用。
“同心圆”示例显示了在绘制自定义控件时,使用浮点精度和抗锯齿可以获得的渲染质量提升。该应用程序的主窗口显示了几个控件,它们是使用高精度和抗锯齿的各种组合绘制的。
RenderHint 枚举为QPainter指定了引擎可能考虑也可能忽略的标志。QPainter::Antialiasing 表示引擎应该为边缘进行抗锯齿计算,QPainter::TextAntialiasing 表示引擎应该抗锯齿文本,QPainter::SmoothPixmapTransform 表示引擎应该使用平滑的像素图转换算法。
渲染提示renderHints() 函数返回一个标志,该标志指定为此画家设置的渲染提示。使用设置渲染提示 setRenderHint() 函数来设置或清除当前设置的渲染提示。
坐标变换
通常,QPainter在设备自己的坐标系(通常是像素)上操作,同时,QPainter支持坐标转换。
最常用的转换是缩放、旋转、平移和剪切。
scale() 函数按给定的偏移量缩放坐标系。
rotate() 函数顺时针旋转它。
translate() 函数平移图形(添加一个给定的偏移量到这些点)。
shear() 函数在原点周围扭曲坐标系。请参见 Affine Transformations示例,以获得剪切坐标系的可视化。
另请参见转换示例,其中显示了转换如何影响QPainter渲染图形的方式。特别是它显示了转换的顺序如何影响结果。
所有的转换操作都在 worldTransform()上运行。
设置世界坐标变换 setWorldTransform() 功能可以替换或添加到当前设置的世界坐标。
resetTransform()函数重置使用 translate(), scale(), shear(), rotate(), setWorldTransform(), setViewport() 和 setWindow() 函数进行的任何转换。
设备转换 deviceTransform()返回从逻辑坐标转换到与平台相关的绘图设备的设备坐标的矩阵。
当使用QPainter绘制时,我们使用逻辑坐标指定点,然后将其转换为绘制设备的物理坐标。逻辑坐标到物理坐标的映射由QPainter的组合转换combinedTransform(),视口viewport() ,窗口window()和世界转换worldTransform()的组合。
视口viewport() 表示指定任意矩形的物理坐标,窗口window() 在逻辑坐标中描述相同的矩形,世界变换worldTransform()与变换矩阵相同。
剪切
QPainter可以将任何绘图操作剪切到矩形、区域或矢量路径中。当前剪辑可使用功能剪辑区域 clipRegion() 和剪辑路径clipPath()。是否首选路径或区域(更快)取决于底层的 paintEngine()。例如,QImage绘制引擎更喜欢路径,而X11绘制引擎更喜欢区域。设置剪切在画家的逻辑坐标中完成。
QPainter剪切后,绘图设备也可能会被剪裁。例如:窗口剪掉了子控件使用的像素,而大多数打印机剪掉了靠近纸张边缘的区域。这个附加的剪切不会反映在剪辑区域 clipRegion() 或快速剪切hasClipping()的返回值中。
合成模式
QPainter提供了合成模式枚举,它定义了用于数字图像合成的规则。
两种最常见的组合形式是Source 和SourceOver。Source 用于将不透明的对象绘制到设备上。在此模式下,源中的每个像素都将替换目标中的相应像素。在合成模式中,SourceOver 是透明的,并被绘制在目标的顶部。
请注意,合成变换是按像素方式操作的。因此,使用图元本身和它的边框是有区别的:边框包含alpha == 0的像素(即图元周围的像素)。这些像素将覆盖其他图像的像素,有效地清除这些像素,而图元仅覆盖自己的区域。
这个Composition Modes 样例,允许您试验各种组合模式,并立即查看结果。
限制
如果使用Qt的基于光栅的绘制引擎的坐标,请注意,虽然可以可以使用正负 2的15次方的坐标,但使用此范围之外的坐标执行的任何绘制都不能保证显示;图形可能被剪切。这是由于在实现中使用了short int。
Qt的outlines generated生成的轮廓只是处理曲线形状时的近似。在大多数情况下,不可能使用另一个贝塞尔曲线段来表示一个贝塞尔曲线段的轮廓,因此Qt通过使用几条较小的曲线来近似该曲线的轮廓。由于性能原因,Qt对这些轮廓使用的曲线数量有限制,因此当使用大的笔宽度或缩放时,轮廓误差会增加。要生成具有较小错误的轮廓,可以使用路径跟踪器 QPainterPathStroker 类,该类具有设置曲线阈值的成员函数,让用户指定容错度。另一个解决方法是首先将路径转换为多边形,然后绘制多边形。
总结
此处略去了帮助文档中关于QPainter底层实现的一段描述。