红胖子,来也!
Qt的图形绘制系统,本篇主要介绍绘图类QPainter。
QPainter类在窗口和其他绘制设备上执行低级绘制。
QPainter提供高度优化的功能来完成大多数图形用户界面程序所需的工作。它能画出从简单线条到复杂形状如饼图和弦等一切图形。它还可以绘制对齐的文本和像素图。通常,它绘制一个“自然”坐标系,但它也可以进行视图和世界变换。QPainter可以对继承QPaintDevice类的任何对象进行操作。
QPainter的常见用法是在窗口的绘制事件中:构造和自定义(例如设置笔或画笔)绘制器。然后画。记住在绘制后销毁QPainer对象。例如:
QPainter的核心功能是绘图,但是类还提供了几个功能,允许您自定义QPainter的设置及其渲染质量,以及其他启用剪辑的功能。此外,还可以通过指定绘制者的合成模式来控制不同形状合并在一起的方式。
函数QPainter::isActive()的作用是:指示绘制程序是否处于活动状态。painter由begin()函数和接受QPaintDevice参数的构造函数激活,end()函数和析构函数将停用它。
与QPaintDevice和QPaintEngine类一起,QPainter构成了qt绘图系统的基础。QPainter是用于执行绘图操作的类。QPaintDevice表示可以使用QPainter绘制的设备。QPaintEngine提供了一个接口,绘图使用它来绘制不同类型的设备。如果绘图处于活动状态,则device()返回及绘图在其上进行绘图的绘图设备,paintEngine()返回绘图当前正在使用的绘图引擎。有关详细信息,请参见绘图系统。
有时,要求在不通用的设备上作画。QPainer支持一个静态函数来执行此操作,setRedirected()。
警告:当paintdevice是一个窗口时,QPainter只能在paintEvent()函数或paintEvent()调用的函数中使用。
可以根据自己的喜好自定义多个设置以使QPainer绘制:
- font()用于绘制文本的字体。如果painter为isActive(),则可以分别使用fontInfo()和fontMetrics()函数检索有关当前设置的字体及其度量的信息。
- brush()定义用于填充形状的颜色或图案。
- pen()定义用于绘制线条或边界的颜色或点画。
- backgroundMode()定义是否有background(),即它是Qt::OpaqueMode或Qt::TransparentMode。
- background()是Qt::OpaqueMode,pen()是点画时,background()才适用。在这种情况下,它描述点画中背景像素的颜色。
- brushOrigin()定义平铺画笔的原点,通常是小部件背景的原点。
- viewport()、window()、worldTransform()构成了painter的坐标转换系统。有关详细信息,请参见“坐标变换”部分和坐标系文档。
- hasClipping()告诉画师是否剪辑。(绘制设备也会被保存)如果painter被截取,它会被保存到clipRegion()。
- layoutDirection()定义绘制文本时画家使用的布局方向。
- worldMatrixEnabled()指示是否启用世界转换。
- viewTransformEnabled()指示是否启用视图转换。
请注意,这些设置中的一些反映了某些绘制设备中的设置,例如QWidget::Font()。QPainter::begin()函数(或等效的QPainter构造函数)从绘制设备复制这些属性。
可以随时通过调用save()函数来保存QPainer的状态,该函数将所有可用的设置保存在一个内部堆栈上(入栈)。restore()函数的作用是:将它们恢复(出栈)。
QPainter提供了绘制大多数基本体的函数:drawPoint()、drawPoints()、drawLine()、drawRect()、drawRoundedRect()、drawEllipse()、drawArc()、drawPie()、drawChord()、drawPolyline()、drawPolygon()、drawConverExpolygon()和drawCubicBezier()。drawRects()和drawLines()这两个函数使用当前的画笔在给定的QRects或QLines数组中绘制给定数量的矩形或线条。
QPainer类还提供了fillRect()函数,该函数用给定的QBrush填充给定的QRect,以及擦除给定矩形内区域的eraseRect()函数。
所有这些函数都有整数和浮点版本(推荐使用浮点数版本)。
测试对象为QWidget,重载paintEvent函数绘制,如下图:
有绘制pixmap/image的函数,即drawPixma()、drawImage()和drawTiledPixmap()。drawPixmap()和drawImage()都会产生相同的结果,只是drawPixmap()在屏幕上更快,而在QPrinter或其他设备上drawImage()可能更快。
有一个drawPicture()函数可以绘制整个QPicture的内容。drawPicture()函数是唯一一个忽略所有绘制设置的函数,因为QPicture有自己的设置。
高分辨率版本的像素映射的设备像素比值大于1(请参见QImageReader,QPixmap::devicePixelRotio())。如果它与基础QPaintDevice的值匹配,则直接将其绘制到设备上,而不应用其他转换。
例如,在高dpi屏幕上绘制64x64像素大小的QPixmap(设备像素比为2)时,设备像素比也为2。请注意,pixmap在用户空间中有效地为32x32像素。qt中基于pixmap大小计算布局几何图形的代码路径将使用此大小。这样做的效果是,像素地图显示为高dpi像素地图,而不是大像素地图。
要使用QPainter获得最佳渲染结果,应使用平台独立的QImage作为绘制设备;即使用QImage将确保结果在任何平台上具有相同的像素表示。
QPainter类还通过其RenderHint枚举和对浮点精度的支持提供了一种控制渲染质量的方法:用于绘制原语的所有函数都具有浮点版本。这些通常与QPainer::Antialiasing渲染结合使用。
抗锯齿是QPainter的渲染默认参数之一。QPainter::RenderHints用于向QPainter指定任何给定引擎可能遵守或不遵守的标志。QPainter::Antialising表示引擎应该尽可能消除原语边缘的混叠,即在原语边缘周围放置额外的像素以平滑边缘。
浮点精度和整数精度之间的差异是一个精度问题,并且在应用程序的主窗口中可见:即使计算圆的几何图形的逻辑是相同的,但浮点确保每个圆之间的空白大小相同,而整数使两个和两个圆成为假装他们属于一起。原因是基于整数的精度依赖于非整数计算的舍入。
RenderHint枚举指定任何给定引擎可能遵守或不遵守的QPainer标志。
- QPainter::Antialiasing:表示引擎应该尽可能地消除原语边缘的锯齿
- QPainter::TextAntialiasing:表示引擎应该尽可能地消除文本的锯齿
- QPainter::SmoothPixMapTransform:表示引擎应该使用平滑的pixmap转换算法。
renderHints() 函数的作用是:返回一个标志,用于指定为此绘制程序设置的渲染参数美剧。使用setRenderHint()函数设置或清除当前设置的RenderHints。
通常,QPainter在设备自己的坐标系统(通常是像素)上工作,但QPainter对坐标转换有很好的支持。
最常用的转换是缩放、旋转、平移和剪切。使用scale()函数按给定的偏移量缩放坐标系,使用rotate()函数顺时针旋转坐标系,使用translate()将坐标系平移(即向点添加给定的偏移量)。还可以使用shear()函数围绕原点扭曲坐标系。有关剪切坐标系的可视化,请参见仿射变换示例。
所有变换操作都在转换worldTransform()上操作。矩阵将平面中的一个点转换为另一个点。有关转换矩阵的详细信息,请参见坐标系和QTransform文档。
setWorldTransform()函数的作用是:替换或添加到当前设置的worldTransform()。resetTransform()函数的作用是:重置使用translate()、scale()、shear()、rotate()、setworldTransform()、setviewport()和setwindow()函数进行的任何转换。deviceTransform()返回从逻辑坐标转换为平台相关绘制设备的设备坐标的矩阵。只有在依赖于平台的句柄上使用平台绘制命令时才需要后一个函数,并且平台不会自然地进行转换。
使用QPainer绘制时,我们使用逻辑坐标指定点,然后将逻辑坐标转换为绘制设备的物理坐标。逻辑坐标到物理坐标的映射由QPainer的combinedTransform()、viewport()和window()以及worldTransform()的组合处理。viewport()表示指定任意矩形的物理坐标,window()以逻辑坐标描述相同的矩形,worldTransform()与转换矩阵相同。
剪切的作用是通过对元素进行剪切来控制元素的可显示区域,也就是在 clip 指定的范围内的内容才能显示出来,正是使用任意形状的 QPainterPath 作为 QPainter的clip,就能绘制出我们想要的效果,例如绘制上图显示的圆形和星形的图片。
QPainer可以将任何绘图操作剪切到矩形、区域或矢量路径。当前剪辑可以使用函数clipRegion()和clipPath())。路径或区域是否首选(更快),取决于基础paintEngine()。例如,QImage绘制引擎偏好路径,而x11绘制引擎偏好区域。设置剪辑是在画图的逻辑坐标中完成的。
QPainter剪切后,绘制设备也可以被剪切。例如,大多数窗口会剪切掉子窗口使用的像素,而大多数打印机会剪切掉靠近纸张边缘的区域。clipRegion()或hasClipping()的返回值不反映此附加剪切。
QPainer提供了QPainter::CompositionMode枚举,它定义了数字图像合成的Porter-Duff规则;它描述了一个模型,用于将一个图像中的像素、源、另一个图像中的像素、目标组合在一起。
两种最常见的组合形式是Source和SourceOver。Source用于将不透明对象绘制到绘制设备上。在此模式下,源中的每个像素都将替换目标中的相应像素。在SourceOver合成模式中,源对象是透明的,并绘制在目标的顶部。
请注意,组合转换操作pixelwise。因此,使用图形基元本身和其边界矩形之间存在差异:边界矩形包含alpha==0的像素(即基元周围的像素)。这些像素将覆盖另一个图像的像素,有效地清除这些像素,而Source只覆盖其自身的区域。
QPainter是一个丰富的框架,它允许开发人员进行各种各样的图形操作,如渐变、合成模式和矢量图形。而QPainer可以跨各种不同的硬件和软件堆栈执行此操作。当然,硬件和软件的底层组合对性能有一定的影响,并且由于排列的数量多,确保每个操作与所有组合模式、画笔、剪切、转换等的各种组合结合起来都很快就接近一个不可能完成的任务。作为一个折衷方案,我们选择了QPainer API和后端的一个子集,在这里,性能可以保证在给定的硬件和软件组合下尽可能好地得到它。
作为高性能引擎,我们关注的后端是:
- 光栅-此后端在纯软件中实现所有渲染,并始终用于渲染为QImages。要获得最佳性能,请仅使用格式类型QImage::Format_ARGB32_Premultipled、QImage::Format_AGB32或QImage::Format_RGB16。任何其他格式(包括QImage::Format_ARGB32)的性能都明显较差。此引擎默认用于QWidget和QPixmap。
- OpenGL2.0(es)-这个后端是硬件加速图形的主要后端。它可以在支持OpenGL 2.0或OpenGL/ES 2.0规范的台式机和嵌入式设备上运行。这包括过去几年生产的大多数图形芯片。可以通过在QOpenGLWidget上使用QPainer来启用引擎。
这些操作包括:
- 简单的转换,意味着平移和缩放,加上0、90、180、270度旋转。
- drawPixmap()结合简单转换和不透明度以及非平滑转换模式(QPainter::SmoothPixMapTransform未作为渲染提示启用)。
- 矩形填充有纯色、双色线性渐变和简单转换。
- 矩形裁剪,具有简单的变换和相交裁剪。
- 合成模式QPainter::CompositionMode_Source和QPainter::CompositionMode_SourceOver。
- 使用纯色和双色线性渐变填充圆角矩形。
- 3x3补丁像素地图,通过QDrawBorderPixmap。
此列表指示在性能至关重要的应用程序中安全使用哪些功能。对于某些设置,其他操作也可能很快,但在广泛使用它们之前,建议在最终运行软件的系统上对它们进行基准测试和验证。也有一些情况下可以使用昂贵的操作,例如当结果缓存在QPixmap中时。
定义数字图像合成支持的模式。合成模式用于指定一个图像(源)中的像素如何与另一个图像(目标)中的像素合并。
请注意,位光栅操作模式(用RasterOp前缀表示)仅在x11和光栅绘制引擎中支持。这意味着在Mac上使用这些模式的唯一方法是通过QImage。笔和画笔(带alpha组件的)不支持RasterOp表示的混合模式。此外,打开QPainer::Antialiasing渲染提示将有效地禁用RasterOp模式。
最常见的类型是SourceOver(通常称为alpha混合,可理解为像素颜色通道),其中源像素在目标像素的顶部混合,这样源的alpha组件定义像素的半透明性。
一些合成模式需要源图像或目标图像中的alpha通道才能产生效果。为了获得最佳性能,最好使用图像格式“format_ARGB8565_Premultiplied”(A-透明,R-红,G-绿,B-蓝,8565依次代表8位、5位、6位、5位)。
当设置合成模式时,它适用于所有绘制操作器、pens、brushes、gradients和pixmap/image。
这个枚举是在Qt4.7中引入或修改的。
PixmapFragmentHints类型是QFlags<PixmapFragmentHint>重定义的。它存储PixmapFragmentHint值或其组合。
RenderInts用于向QPainer指定任何给定引擎可能遵守或不遵守的标志。
RenderInts类型是QFlags<RenderInt>预定义类型。它存储RenderInt值的一个或组合。
到此这篇qpainter底层(qpainter::begin)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/80300.html