1.概览

QPainter类在widgets和其他绘图设备上执行低级的绘制。
QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状,如饼状与和弦。它还可以绘制对齐的文本和像素图。通常,它会绘制一个“自然”坐标系,但也可以进行视图和视角的变换。QPainter可以对继承QPaintDevice类的任何对象进行操作。
QPainter的常见用法是在widgets的paintEvent函数中:构造和自定义一个(例如设置笔或笔刷)painter对象,然后画图。请记住在绘制后销毁QPainter对象。例如:

void SimpleExampleWidget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.setPen(Qt::blue);painter.setFont(QFont("Arial", 30));painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

QPainter的核心功能是绘图,但该类还提供了几个函数,允许您自定义QPainter的设置及其渲染质量,以及其他启用剪裁的函数。此外,您还可以通过指定QPainter的构图模式来控制不同形状如何合并在一起。

isActive()函数的作用是:指示painter是否处于活动状态。painter由begin()函数和接受QPaintDevice参数的构造函数激活。end()函数和析构函数将其停用。

QPainter与QPaintDevice和QPaintEngine类一起构成了Qt油漆系统的基础。QPainter是用于执行绘图操作的类。QPaintDevice表示可以使用QPainter在其上绘制的设备。QPaintEngine提供了一个接口,painter可以使用这个接口来绘制不同类型的设备。如果painter处于活动状态,device()返回painter在其上绘制的绘制设备,paintEngine()返回painter当前正在操作的绘制引擎。

有时,让别人在一个不寻常的QPaintDevice上画画也是可以的,QPainter有一个静态函数来实现这个功能,setRedirected()。

警告:当paintdevice是一个widget时,QPainter只能在paintEvent()函数或由paintEvent()调用的函数中使用。

2.设置

你可以根据您的偏好自定义QPainter,然后进行绘制:

  • font():是用于绘制文本的字体。如果QPainter是active(),你可以分别使用fontInfo()和fontMetrics()函数来检索当前设置的字体及其指标的信息。
  • brush():定义用于填充形状的颜色或图案。
  • pen():定义用于绘制线条或边界的颜色或点。
  • backgroundMode():定义是否存在background(),即Qt::OpaqueMode或Qt::TransparentMode。
  • background():仅适用于backgroundMode()为Qt::OpaqueMode且pen()为点画。在这种情况下,它描述了点画中背景像素的颜色。
  • brushOrigin():定义了平铺画笔的起源,通常是小部件背景的起源。
  • viewport(), window(), worldTransform()组成了QPainter的坐标转换系统。有关更多信息,请参阅坐标转换部分和坐标系统文档。
  • hasClipping():告诉我们QPainter是否在剪辑,如果QPainter在剪辑,它将剪辑到clipRegion()。
  • layoutDirection():定义绘制文本时QPainter使用的布局方向。
  • worldMatrixEnabled():表示是否启用世界转换。
  • viewTransformEnabled():告诉是否启用视图转换。

请注意,其中一些设置镜像了一些绘制设备的设置,例如QWidget::font()。QPainter::begin()函数(或等效的QPainter构造函数)从绘制设备复制这些属性。

你可以在任何时候通过调用save()函数来保存QPainter的状态,save()函数将所有可用的设置保存在一个内部堆栈中。restore()函数将它们弹出。

3.绘图

QPainter提供了绘制大多数基本图形元素的函数:drawPoint(), drawPoints(), drawLine(), drawRect(), drawRoundedRect(), drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(), drawPolygon(), drawConvexPolygon()和drawCubicBezier()。两个方便的函数,drawRects()和drawLines(),使用当前钢笔和画笔在给定的QRects或QLines数组中绘制给定数量的矩形或线条。

QPainter类还提供了fillRect()函数,它用给定的QBrush填充给定的QRect,以及eras直立()函数,它擦除给定矩形内的区域。

所有这些函数都有整数和浮点数版本。

如果您需要绘制一个复杂的形状,特别是如果您需要反复这样做,考虑创建一个QPainterPath并使用drawPath()绘制它。

QPainter还提供了fillPath()函数,该函数用给定的QBrush填充给定的QPainterPath,以及strokePath()函数绘制给定路径的轮廓(即描边路径)。

也请参阅矢量变形的例子,它展示了如何使用先进的矢量技术来使用QPainterPath绘制文本,梯度的例子,它显示了Qt中可用的不同类型的梯度,Path stroke示例展示了Qt的内置破折号模式,并展示了如何使用自定义模式来扩展可用模式的范围。

文本绘制是使用drawText()完成的。当您需要细粒度的定位时,boundingRect()会告诉您给定的drawText()命令将在哪里绘制。

4.绘制位图和图片

有绘制像素图/图像的函数,即drawPixmap(), drawImage()和drawTiledPixmap()。drawPixmap()和drawImage()都产生相同的结果,除了drawPixmap()在屏幕上更快,而drawImage()可能在QPrinter或其他设备上更快。

有一个drawPicture()函数,它绘制整个QPicture的内容。drawPicture()函数是唯一忽略所有painter设置的函数,因为QPicture有自己的设置。

5.绘制高分辨率的位图和图片

高分辨率版本的像素图的设备像素比值大于1(参见QImageReader, QPixmap::devicePixelRatio())。如果它与底层QPaintDevice的值匹配,则直接将其绘制到设备上,不应用任何额外的转换。
例如,在高DPI屏幕上绘制64x64像素大小的QPixmap,设备像素比为2,而设备像素比也为2。请注意,像素图在用户空间中实际上是32x32像素。Qt中基于位图大小计算布局几何的代码路径将使用此大小。这样做的净效果是,位图显示为高DPI的位图,而不是大的位图。

RenderHint枚举指定了QPainter的标志,这些标志可能被任何给定的引擎所遵守,也可能不被遵守。QPainter::Antialiasing表示引擎应该在可能的情况下消除原语的边缘,QPainter::TextAntialiasing表示引擎应该在可能的情况下消除文本,QPainter::SmoothPixmapTransform表示引擎应该使用一个平滑的像素图转换算法。

renderHints()函数的作用是:返回一个标志,该标志指定为该画家设置的渲染提示。使用setRenderHint()函数设置或清除当前设置的RenderHints。

6.坐标变换

通常,QPainter在设备自己的坐标系(通常是像素)上操作,但QPainter对坐标转换有很好的支持。

最常用的转换是缩放、旋转、平移和剪切。使用scale()函数按给定的偏移量缩放坐标系统,rotate()函数顺时针旋转坐标系统,translate()函数平移坐标系统(即为点添加一个给定的偏移量)。您还可以使用shear()函数围绕原点扭曲坐标系统。关于剪切坐标系统的可视化,请参阅仿射变换示例。
请参见转换示例,该示例显示了转换如何影响QPainter渲染图形原语的方式。特别地,它显示了转换的顺序如何影响结果。

所有的转换操作都作用于转换worldTransform()。矩阵将平面上的一点变换为另一点。有关转换矩阵的更多信息,请参阅Coordinate System和QTransform文档。

setWorldTransform()函数可以替换或添加到当前设置的worldTransform()。resetTransform()函数重置任何使用translate()、scale()、shear()、rotate()、setWorldTransform()、setViewport()和setWindow()函数进行的转换。deviceTransform()返回一个矩阵,该矩阵将平台依赖的绘制设备的逻辑坐标转换为设备坐标。只有在平台相关句柄上使用平台绘制命令时才需要后一个函数,而且平台本身不进行转换。

当使用QPainter绘图时,我们使用逻辑坐标指定点,然后将这些点转换为绘图设备的物理坐标。逻辑坐标到物理坐标的映射是由QPainter的combinedTransform()处理的,它是viewport()、window()和worldTransform()的组合。viewport()表示指定任意矩形的物理坐标,window()用逻辑坐标描述相同的矩形,worldTransform()与转换矩阵相同。
参见坐标系

7.剪辑

QPainter可以剪切任何绘图操作到一个矩形,一个区域,或矢量路径。当前的剪辑可以使用函数clipreregion()和clipPath()。路径还是区域是首选(更快)取决于底层的paintEngine()。例如,QImage绘制引擎优先选择路径,而X11绘制引擎优先选择区域。设置剪辑在画家的逻辑坐标中完成。
在QPainter剪切之后,油漆装置也可以剪切。例如,大多数小部件会夹掉子部件使用的像素,大多数打印机会夹掉纸张边缘附近的一块区域。这个额外的剪切不会反映在clipreregion()或hasClipping()的返回值中。

8.合成模式

QPainter提供了CompositionMode枚举,它定义了数字图像合成的Porter-Duff规则;它描述了一个模型,用于将一个图像(源图像)中的像素与另一个图像(目标图像)中的像素相结合。
两种最常见的组合形式是Source和SourceOver。源用于在绘制设备上绘制不透明对象。在这种模式下,源中的每个像素替换目标中的相应像素。在SourceOver组合模式中,源对象是透明的,并绘制在目标的顶部。
注意,合成变换是按像素进行的。因此,使用图形原语本身和它的边界矩形之间有一个区别:边界矩形包含alpha == 0的像素(即围绕原语的像素)。这些像素将覆盖其他图像的像素,有效地清除那些,而原语只覆盖自己的区域。

9.局限性

如果你正在使用Qt的基于栅格的绘图引擎的坐标,需要注意的是,虽然可以使用大于+/- 215的坐标,但任何在这个范围之外的坐标执行的绘图都不能保证显示出来;这幅图可以剪掉。这是由于在实现中使用了短int。
Qt的描边器生成的轮廓在处理曲线形状时只是一个近似。在大多数情况下,用另一个bezier曲线段来表示一个bezier曲线段的轮廓是不可能的,因此Qt通过使用几个较小的曲线来近似曲线轮廓。出于性能原因,Qt对这些轮廓使用的曲线数量是有限制的,因此当使用较大的钢笔宽度或缩放时,轮廓误差会增加。为了生成带有较小错误的轮廓,可以使用QPainterPathStroker类,该类具有setCurveThreshold成员函数,让用户指定容错性。另一个解决方法是先将路径转换为多边形,然后再绘制多边形。

10.性能

QPainter是一个丰富的框架,它允许开发者进行各种各样的图形操作,比如渐变、组合模式和矢量图形。QPainter可以通过各种不同的硬件和软件栈实现这一点。自然地,硬件和软件的潜在组合对性能有一些影响,确保每一个操作与所有组合模式、笔刷、剪切、转换等的各种组合相结合是快速的,因为排列的数量几乎是不可能的任务。作为一种折衷,我们选择了QPainter API和后端的一个子集,其中的性能可以保证在给定的硬件和软件组合下,我们可以得到尽可能好的性能。

作为高性能引擎,我们关注的后端是:

  • 栅格——这个后端在纯软件中实现了所有的渲染,并且总是用于渲染QImages。为了优化性能,只使用格式类型QImage:: format_argb32_premultiplying, QImage::Format_RGB32或QImage::Format_RGB16。任何其他格式,包括QImage::Format_ARGB32,性能都要差得多。该引擎默认用于QWidget和QPixmap。
  • OpenGL 2.0 (ES) ——这个后端是硬件加速图形的主要后端。它可以在支持OpenGL 2.0或OpenGL/ES 2.0规范的台式机和嵌入式设备上运行。这包括过去几年生产的大多数显卡。引擎可以通过在QOpenGLWidget上使用QPainter来启用。

这些操作是:

  • 简单的转换,意味着平移和缩放,加上0,90,180,270度旋转。
  • drawPixmap()结合简单的转换和不透明度与非平滑转换模式(QPainter::SmoothPixmapTransform不启用作为渲染提示)。
  • 矩形填充与纯色,双色线性梯度和简单的变换。
  • 矩形剪辑与简单的转换和相交剪辑。
  • 组合模式QPainter::CompositionMode_Source和QPainter::CompositionMode_SourceOver
  • 圆角矩形填充使用纯色和双色线性梯度填充。
  • 3个x3补丁pixmaps,通过qDrawBorderPixmap。

这个列表指出了在性能至关重要的应用程序中安全使用哪些特性。对于某些设置,其他操作可能也很快,但在广泛使用它们之前,建议在软件最终将运行的系统上对它们进行基准测试和验证。也有一些情况下,可以使用昂贵的操作,例如结果缓存在QPixmap中。
参见QPaintDevice、QPaintEngine、Qt SVG、基本绘图示例和绘图实用程序函数。

QT QPainter相关推荐

  1. Qt QPainter::end: Painter ended whith 2 saced states

    在使用Qt  QPainter 的时候,有时会遇到"QPainter::end: Painter ended whith 2 saced states" 这时由于我们在使用的QPa ...

  2. Qt QPainter基本绘图

    Qt QPainter基本绘图 QPen QBrush 渐变填充 QFont 基本图形元件 QPainterPath QPainter::CompositionMode 实例1 QPainter绘图操 ...

  3. Qt / QPainter、QPen、QBrush 如何理解

    之前一直不是很理解上述三个类,直到看到了一篇博客,真的是茅塞顿开啊!下面是该博客的部分内容: 零.介绍 QPen 是画笔,用来绘制图形的轮廓线,以及定义轮廓线的颜色.样式和属性: QBrush 是画刷 ...

  4. Qt QPainter鼠标绘制线条、矩形、多边形

    Qt通过鼠标绘制线条.矩形.多边形本质都是根据鼠标的坐标位移,使用QPainter的自带的函数进行绘制.具体代码如下: graphicspainter.h #ifndef GRAPHICSPAINTE ...

  5. Qt QPainter CompositionMode

    QPainter的CompositionMode 即 将两张图以某种mode融合在一起: 假设有图src.图dst.融合后的结果图ret,具体应用就是先在ret上画了dst,然后再以某种mode将sr ...

  6. VS+QT QPainter 绘制直线

    1.打开软件,创建一个GUI项目文件. 2.编写.h(Draw2.h)文件代码,如下: #pragma once#include <QtWidgets/QMainWindow> #incl ...

  7. QT QPainter::antialiasing QPainter::textAntialiasing 反走样、抗锯齿探究

    QT中使用QPainter 进行自行绘图的时候,为了防止"锯齿"的出现,我们会经常使用抗锯齿属性,也叫反走样, 既: QPainter::Antialiasing //绘图抗锯齿 ...

  8. Qt QPainter 调用setRenderHint(QPainter::Antialiasing, true)什么意思 QGraphicsView的该函数

    setRenderHint(QPainter::Antialiasing, true);//反走样功能,调用反锯齿功能 在QGraphicsItem中使用旋转,直线确实会出现锯齿,使用这个会不会好一些 ...

  9. 基于Qt QPainter自绘扇形统计图

    不多说,直接上效果图: 部分代码呈现: tongjitu.h中 #define MYTONGJITU_H #include <QWidget> #include "tongjit ...

  10. 关于字体绘制的baseline (QT 和 D2D)

    常规字体绘制API调用: QT:QPainter::drawText D2D: ID2D1RenderTarget::DrawText 以上字体绘制某些特殊效果无法达到, 我们可以用Path绘制字体: ...

最新文章

  1. Python图像处理介绍--彩色图像的直方图处理
  2. wxWidgets:wxTopLevelWindow类用法
  3. Wireshark安装和基本使用
  4. SAP odata模型缓存校验机制
  5. linux 有名管道pipe,linux 用無名管道pipe和有名管道fifo實現線程間通信
  6. 文件另存为时名称会改变_易经:人处在困境时,不要焦虑,改变固定习惯,就会迎来转机...
  7. docker -v 覆盖了容器中的文件_「安定坊」安全卫士-容器漏洞评估
  8. 力扣题目——107. 二叉树的层序遍历 II
  9. notepad++下的字体设置
  10. mysql 主从机器 触发器 的测试,完全正常 没有问题
  11. PyQt5教程(七)——实现QQ登录界面(一、Qt Designer创建界面,Eric6创建项目)
  12. POI实现word转html(带图片),实现word在线预览
  13. matlab分析系统灵敏度,matlab灵敏度分析函数
  14. 生物信息学_测序技术(一)DNA测序
  15. 树莓派-内核启动报错mmc0: error -5 whilst initialising MMC card
  16. 关于php上传多张图片时,选择图片后就可以预览的问题
  17. 如何给原图添加文字水印和图片水印
  18. spring注解方式整合Dubbo源码解析
  19. 计算机网络自顶向下方法课程实验一华为三层交换机路由器配置静态路由
  20. 制作一个简单的Android版的音乐播放器

热门文章

  1. 从空运物流到无人机物流,圆通将战火烧到了时效件
  2. 如何证明服从卡方分布_卡方分布
  3. 最全H桥电机驱动模块L298N原理及应用
  4. 读书笔记-人月神话10
  5. python能干什么知乎-python能做什么知乎
  6. Post 页面数据,使用boundary来格式化
  7. matlab表示dbm,[转载]dBm换算成mW
  8. Excel宏教程 (宏的介绍与基本使用)
  9. dnf时装补丁教程_【时装补丁制作】消灭伸手党!最详细的图文教程~
  10. word文档的尺寸和字号对照表