QPainter类在窗口部件(widgets)和其它绘图设置上进行底层的绘图操作。
QPainter提供 了高度优化的函数,来进行图形界面程序 所需要的大部分绘图工作。 它可以绘制 从简单的直线到复杂的形状(例如饼图 (pies) 以及弦 (chords) )在内的 任何东西 。 它还可以以对齐的方式绘制文字,还可以绘制位图。 一般情况下,它按照一个“自然的”坐标系统来绘制,但是 也可以做视图(view)和世界(world)的变换(transformation)的。 QPainter 可在任何一个继承了 QPaintDevice 类的对象上工作。
QPainter 的常规用法是在一个窗口部件的绘图事件中使用:构造并且设置 (例如,设置画笔 (pen)和画刷(brush) )该绘图器。然后绘制 。记住 ,在绘图完毕之后,要销毁该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 的一些选项和渲染质量; 另一些可让妳实现修剪 (clipping)功能。另外 ,妳可以指定绘图器的合成(composition)模式, 以便控制不同的形状是如果融合在一起的。
isActive ()函数指示 着该绘图器目前是否处于活跃状态。 一个绘图器可由两种方法来激活: begin ()函数 ;接收一个 QPaintDevice 参数的构造函数。 end ()函数 ,和析构函数,都能使它变为非激活状态。
QPainter 与 QPaintDevice 和 QPaintEngine 类一起构成Qt 绘图系统的基础。 QPainter 是用来做绘图操作的类。 QPaintDevice 代表 的是一个可用QPainter 在其上绘图的设备。 QPaintEngine 提供 了接口,使得绘图器可 在不同类型的设备上绘制。如果绘图 器处于活跃状态,那么 , device ()返回 该绘图器当前在其上绘图的绘图设备, 而 paintEngine ()返回 该绘图器当前在其上进行操作的绘图引擎。 要了解更多信息,参考 绘图系统 。
某些时候,可能需要 让其它组件来在某个非同一般的 QPaintDevice 上绘图。 QPainter支 持使用一个静态函数来达到这个目的,即 setRedirected ()。
警告: 如果绘图 设备是一个窗口部件,那么 , QPainter 只可在一个paintEvent()函数里或者被paintEvent()调用的函数里使用 ;除非 妳设置了 Qt::WA_PaintOutsidePaintEvent 这个窗口部件属性。 在 Mac OS X 中,即使设置 了这个属性,妳也只能在paintEvent()函数中做绘图操作。
有多种设置信息,妳可以对其进行自定义,以让QPainter 按照妳的需要来绘图:
•. font () ,用来绘制文字的字体。如果绘图 器处于活跃状态( isActive ()),那么 , 妳可以分别使用 fontInfo ()和 fontMetrics ()函数来获取当前使用 的字体 和字体尺寸(metrics)的信息。
•. brush () ,用来填充各种形状 的颜色或图样(pattern)。
•. pen () ,用来绘制直线或边线的颜色或点线模式(stipple)。
•. backgroundMode () ,是否要有一个背景色( background ()), 也就是说, 它或者是 Qt::OpaqueMode ,或者是 Qt::TransparentMode 。
•. background () ,仅当这种情况下有效: backgroundMode () 是 Qt::OpaqueMode 并且 pen () 是一个点线模式。 在那种情况下,它指明的是点线模式中的背景像素的颜色。
•. brushOrigin () ,平铺画刷的起始点, 一般是窗口部件的背景的起始点。
•. viewport () 、 window () 、 worldTransform ()组成 该绘图器的坐标转换系统。 要了解更多信息,就参考 坐标转换 小节和 坐标系统 文档。
•. hasClipping () ,该绘图器是否在进行任何形式的修剪。 (绘图设备本身也会有修剪动作的。)如果 该绘图器有修剪动作的话,它会按照 clipRegion ()来修剪。
•. layoutDirection () ,该绘图器在绘制文字时使用的布局方向。
•. worldMatrixEnabled () ,是否已经启用了世界变换。
•. viewTransformEnabled () ,是否已经启用了视图变换。
注意 , 这里的某些设置,在某些绘图设备上,只是它们 的设置信息的副本 ,例如 QWidget::font ()。 QPainter::begin ()函数 (或者QPainter 的构造函数 )会从绘图设备中复制这些属性。
妳可以在任何时候调用 save ()函数来保存该QPainter 的状态,它会将当前可用的设置信息都保存到一个内部栈中。 restore ()函数 会将它们恢复出来。
QPainter提供 了函数来绘制大部分的图元(primitives): drawPoint () 、 drawPoints () 、 drawLine () 、 drawRect () 、 drawRoundedRect () 、 drawEllipse () 、 drawArc () 、 drawPie () 、 drawChord () 、 drawPolyline () 、 drawPolygon () 、 drawConvexPolygon () 和 drawCubicBezier () 。两个便利函数 , drawRects () 和 drawLines () ,会使用当前的画笔和画刷来将指定的 QRects 或 QLines 数组中指定个数的矩形或直线绘制出来。
QPainter 类还提供了 fillRect ()函数, 它会使用指定的 QBrush 来填充指定的 QRect 。 还有 eraseRect ()函数, 会擦除掉指定矩形内部 的区域。
这些函数都同时有整数和浮点数两个版本。
|
基本绘图示例 基本绘图 示例展示了,如果使用QPainter 类来 以多种风格显示基本的图元。 |
如果 妳需要绘制复制的形状,尤其是妳需要重复绘制的时候, 可以考虑创建一个 QPainterPath ,然后使用 drawPath ()来绘制它。
绘图路径示例 QPainterPath 类提供了一个容器,用来记录绘图操作, 这就使得妳可以构造并复用图形形状 。 绘图路径 这个示例,演示了如果使用绘图路径 来构造复杂的形状,以用来渲染。 |
|
QPainter 还提供了 fillPath ()函数, 它会使用指定的 QBrush 来填充指定的 QPainterPath 。 还有 strokePath ()函数, 它会绘制出指定的路径的轮廓( 也就是说,勾勒出该路径 )。
参考 下列示例。 矢量变形 示例 ,演示 的是,如何使用先进的矢量技术和 QPainterPath 来绘制文字。 渐变 示例,演示 的是,Qt 中可用的不同类型的渐变。 路径勾勒 示例 ,演示的是, Qt内置 的点线模式, 以及,如果何用自定义图样来扩充可用图样。
矢量变形 |
渐变 |
路径勾勒 |
|
|
|
有一些函数可用来绘制位图/图片,即 drawPixmap ()、 drawImage ()和 drawTiledPixmap ()。 drawPixmap () 和 drawImage () 会产生相同的结果,唯一 的不同之处是, drawPixmap () 在屏幕上绘制时会更快,而 drawImage ()在 QPrinter 或其它设备上绘制时会更快。
文字 的绘制是使用 drawText ()来实现的。如果 妳想要精细地控制文字的位置,那么, 可以使用 boundingRect ()函数来得知指定的 drawText ()命令会将文字绘制在什么位置。
有一个 drawPicture ()函数, 它会绘制整个 QPicture 的内容。 drawPicture ()函数 是唯一一个会忽视当前绘图器的所有设置信息的命令,因为 QPicture 拥有 它自己的设置。
要想从QPainter 获得最佳的渲染结果, 妳应当使用 与平台无关的 QImage 作为绘图设备; 也就是说,使用 QImage 的话, 可以确保绘制 出来的结果在任何平台上都是完全一样的。
QPainter 类还提供了一种手段来控制渲染质量, 可通过 RenderHint 枚举来进行这种控制。另外 还提供了对浮点数精度的支持:所有 的用来绘制图元的函数都有其浮点数版本。 这些手段经常与 QPainter::Antialiasing 这个渲染建议(hint)一起使用。
|
同心圆示例 同心圆示例 ,演示 的是, 在绘制自定义的窗口部件时,使用浮点 数精度和抗锯齿技术 所 能达到的渲染质量的提升。 这个程序的主窗口显示多个窗口部件,它们 是使用不同精度和抗锯齿选项的组合来绘制的。 |
RenderHint 枚举 向QPainter 指定一些标志位,它们可能 会被指定的引擎采用,也可能会被忽略。 QPainter::Antialiasing 指示引擎应当 在可以的情况下 将图元的边线做抗锯齿处理。 QPainter::TextAntialiasing 指示引擎应当 在可以的情况下将文字做抗锯齿处理。 QPainter::SmoothPixmapTransform 指示引擎应当采用 一种平滑的位图变换算法。 HighQualityAntialiasing 是一个 只被开放图像 库(OpenGL)支持的渲染建议,指示引擎应当使用片段程序 (fragment programs)和 离屏渲染(offscreen rendering)来做抗锯齿处理。
renderHints ()函数返回 一个标志位集合,其中包含了当前被设置到该绘图器上的渲染建议。使用 setRenderHint ()函数 来设置或清除当前已经设置的 渲染建议 。
一般情况下,QPainter会在设备自身的坐标系统(通常 是像素 )上操作,但是QPainter对坐标变换支持得狠好。
无变换 |
rotate () |
scale () |
translate () |
|
|
|
|
最常见的变换是缩放、旋转、平移(translation)和修剪 (shearing) 。使用 scale ()函数 来按照指定的偏移来缩放坐标系统,使用 rotate ()函数 来将坐标系统按照顺时针方向旋转,使用 translate ()函数 来平移( 即,对那些点加上一个指定的偏移值 )。 妳还可以使用 shear ()函数将坐标系统扭曲成原点周围的一小块区域。参考 仿射变换 示例, 它展示了一个扭曲过的坐标系统。
参考 变换 示例,演示 了 , 变换 是如何影响到QPainter 渲染图元的方式的。尤其 是,它演示了,变换的顺序是如何影响到结果的。
仿射变换示例 仿射变换 示例,演示 了Qt 在绘图操作中应用仿射变换的能力。 这个示例也允许用户试验 不同的变换,并且立即观察其结果。 |
|
所有 的变换操作都是在 worldTransform ()这个变换对象上进行的。 一个矩阵将平面中的某个点变换到另一个点。 要想了解更多关于变换矩阵的信息,就参考 坐标系统 和 QTransform 文档。
setWorldTransform ()函数 可以替换或者向当前的 worldTransform ()中添加变换操作。 resetTransform ()函数 将以下函数 所产生的所有变换都重置: translate () 、 scale () 、 shear () 、 rotate () 、 setWorldTransform () 、 setViewport () 和 setWindow () 。 deviceTransform ()返回 的是,某个 与平台相关的设备的变换矩阵,该矩阵是用来将本地坐标变换为设备坐标的。 后一个函数仅在以下情况下才是需要使用的:采用平台相关 的绘图命令来在平台相关的句柄(handle)上绘图,而该平台又不提供原生的变换功能。
在使用QPainter 绘图时, 我们使用本地坐标来指定各个点, 它些坐标随后会被转换为绘图设备 上的物理坐标。 这个将本地坐标映射为物理坐标的过程,是由QPainter 的 combinedTransform ()来管理的, 而这个变换对象是 viewport ()、 window ()和 worldTransform ()组合的结果。 viewport ()代表 着指定了一个任意矩形的物理坐标, window ()使用本地坐标描述 了相同的那个矩形, 而 worldTransform () 与变换矩阵等价。
参考 坐标系统
QPainter 可将任意的绘图操作修剪为限定在一个矩形、一个区域或一个矢量路径中。 可使用 clipRegion ()和 clipPath ()来获取当前的修剪参数。究竟 该使用路径还是区域(哪个更快),取决于底层的绘图引擎( paintEngine ())。例如, QImage 绘图引擎 更适合于使用路径,而X11 绘图引擎更适合于使用区域。修剪参数 是按照绘图器的本地坐标来设置的。
在 QPainter 做过修剪之后,绘图设备可能也会做修剪。例如, 大部分窗口部件都会将子代部件所使用的像素都修剪掉, 而大部分打印机都会将纸张边缘附近的内容修剪掉。 这种附加的修剪操作不会在 clipRegion ()或 hasClipping ()的返回值中反映出来。
QPainter提供 了 CompositionMode 枚举, 它定义的是对于数字图片合成的破特-达夫(Porter-Duff)规则; 它描述的是一个模型,该模型控制的是,如何将源图片里的像素与目标图片里的像素组合在一起。
最常用的两种合成形式就是 源 和 源覆盖 。 源 用来 将完全不透明的对象绘制到绘图设备上。 在这种模式下, 源图片里的每个像素都会替换掉目标图片中的对应像素。 在 源覆盖 这种合成模式中, 源对象是透明的,会绘制 到目标图片上,追加了一层。
注意,合成变换是按照像素来进行的。 这就导致了 ,使用图元本身 和使用它的包含矩形是不一样的:包含矩阵 中含有alpha == 0 的像素( 即,图元周围的那些像素 )。 这些像素会覆盖另一张图片上对应的像素,一般来说就是擦除了那些像素, 而图元呢,只会覆盖它自身的区域。
|
合成模式示例 合成模式 示例,位于Qt 的示例目录中,允许 妳试验 不同的合成模式,并且立即观察到结果。 |
如果 妳使用的是 Qt 的光栅图(raster)绘图引擎,那么 ,有一点必需注意,尽管 可以使用绝对 值 大于+/- 2 15 的坐标,但是 , 在这个区域以外所做的绘图操作将不被确保是一定能够显示出来 的;绘图内容可能 会被修剪。 这是因为,代码里面使用 的是短整型 ( short int ) 。
在处理那种 弯曲的形状时,Qt 的勾勒器(stroker)所产生的轮廓只是一个近似值。 在大部分情况下, 是不可能使用另一个贝塞尔曲线线段来表示某个贝塞尔曲线线段的轮廓的 ,所以Qt 使用多个较小的曲线来近似表示该曲线的轮廓。由于性能 上的原因,Qt 用来表示这些轮廓的曲线的数量是有限的,所以 ,在使用较大的画笔或缩放比例时,轮廓 的偏差就增加了。 要想生成偏差较小的轮廓,可以使用 QPainterPathStroker 类, 它有一个setCurveThreshold 成员函数, 可以让用户来指定对偏差的容忍度。 另一个绕过方式就是,将路径转换成 多边形,再绘制那个多边形。
QPainter是一个功能强大 的框架,允许开发 者进行多种图像操作,例如渐变、合成模式选择和矢量图形。而且,QPainter可以在多种不同的硬件和软件栈上进行这些工作。 一般情况下,底层 的硬件和软件组合会产生某些性能影响, 这就使得 : 要想确保任何 一个单个的操作在与所有的那些合成模式、画笔、修剪、变换选项都组合在一起时仍能有极高 的性能的话,几乎 是一个不可能的任务,因为 其组合状况实在是太多了。作为 一个折衷, 我们选择 了 一组QPainter 接口的集合和后端, 在选择的这个集合 的硬件和软件组合 里, 我们可以确保,性能 是尽可能的好。
我们致力于让其成为高性能引擎的后端包括:
•. 光栅 - 这个后端,以纯软件的形式来实现所有的渲染操作,一直被用来向QImages 渲染图片。 要达到最佳性能,就只使用 QImage::Format_ARGB32_Premultiplied 、 QImage::Format_RGB32 或 QImage::Format_RGB16 这几种格式类型。任何其它格式 ,包括 QImage::Format_ARGB32 , 都会有明显的性能下降。 这种引擎也是QWS 上的默认引擎。 可在任何操作系统/硬件/软件的组合中,通过 -graphicssystem raster 命令行选项来将它作为默认图形系统。
•. 开放图形 库 2.0 (ES) – 这个后端,是带有硬件加速图形功能的系统上的主要后端。 它可以在支持开放图形库2.0 或开放图形库/嵌入式系统(OpenGL/ES)2.0 规范的桌面机器和嵌入式设备上使用。 这就包括了最近几年生产的大部分显卡。 在底层系统支持的情况下, 可通过 以下手段来启用这个引擎: 在一个 QGLWidget 上使用QPainter;或者在命令行传递 -graphicssystem opengl 参数。
•. 开放矢量图形 ( OpenVG ) - 这个后端实现的是 科纳斯组织(Khronos) 的二维和矢量图形标准。 它是带有开放矢量图形硬件支持的嵌入式设备的首选引擎。 在底层系统支持的情况下, 可在命令行传递 -graphicssystem openvg 参数 来启用这个引擎。
这些操作包括:
•.简单变换, 即,平移 和缩放,外加度 0、90、180、270度 的旋转。
•. drawPixmap() ,同时带有简单变换和透明度,以及非平滑的变换模式( 在渲染建议中不启用 QPainter::SmoothPixmapTransform )。
•.使用固定颜色、两色线性渐变和简单变换来填充矩形。
•.使用简单变换和交集修剪来做矩形修剪。
•. QPainter::CompositionMode_Source 和 QPainter::CompositionMode_SourceOver 两种合成模式。
•.使用固定颜色和两色线性渐变来填充圆角矩形。
•. 在qDrawBorderPixmap 中使用 3x3 的补丁(patched)位图。
以上清单,给出了一个参考,在性能非常重要的程序里,哪些功能 是可以放心使用的。对于特定 的配置(setups),其它操作可能也会非常快,但是, 在大量使用那些操作之前,建议先在妳们的软件将要运行 的系统上做个性能测试以验证这一点。另外 ,在某 些情况 下 ,耗时 的操作也可以随意使用,例如,绘图结果 是在一个 QPixmap 中缓冲的。
参考 QPaintDevice 、 QPaintEngine 、 QtSvg模块 、 基础绘图示例 和 绘图辅助函数 。
这是一个重载函数。
绘制 一条从( x1 , y1 )到( x2 , y2 )的线段,并且将当前的画笔位置设置成( x2 , y2 )。
这是一个重载函数。
将绘图器的画笔的样式设置成 Qt::SolidLine ,宽度设置成0,颜色设置成 color 。
未知美人
未知美人
未知美人
未知美人
未知美人
HxLauncher: Launch Android applications by voice commands