当前位置 博文首页 > Allen Roson:QT QPainter

    Allen Roson:QT QPainter

    作者:[db:作者] 时间:2021-06-22 21:12

    QPainter类在小部件和其他绘制设备上执行低级绘制。
    QPainter提供了高度优化的功能来完成大多数图形GUI程序所需的工作。它可以画从简单的线条到复杂的形状,如馅饼和和弦。它还可以绘制对齐的文本和像素图。通常,它会绘制一个“自然”坐标系,但也可以进行视图和世界变换。QPainter可以对继承QPaintDevice类的任何对象进行操作。
    QPainter的常见用法是在小部件的paint事件中:构造和自定义(例如设置笔或笔刷)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的设置及其渲染质量,以及其他启用剪裁的函数。此外,您还可以通过指定画家的构图模式来控制不同形状如何合并在一起。
    函数的作用是:指示画师是否处于活动状态。画师由begin()函数和接受QPaintDevice参数的构造函数激活。end()函数和析构函数将其停用。
    QPainter与QPaintDevice和QPaintEngine类一起构成了Qt油漆系统的基础。QPainter是用于执行绘图操作的类。QPaintDevice表示可以使用QPainter在其上绘制的设备。QPaintEngine提供了一个接口,画家可以使用这个接口来绘制不同类型的设备。如果画家处于活动状态,device()返回画家在其上绘制的绘制设备,paintEngine()返回画家当前正在操作的绘制引擎。有关详细信息,请参见绘制系统。
    有时它是可取的,让别人画在一个不寻常的设备。QPainter支持静态函数setRedirected()。

    ?

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

    ?

    设置
    您可以自定义多个设置,以便根据自己的首选项进行QPaint绘制:
    font()是用于绘制文本的字体。如果painter为active(),则可以分别使用fontInfo()和fontMetrics()函数检索有关当前设置字体及其度量的信息。
    brush()定义用于填充形状的颜色或图案。
    pen()定义用于绘制线或边界的颜色或点画。
    backgroundMode()定义是否存在background(),即它是Qt::OpaqueMode还是Qt::TransparentMode。
    backgroundMode()为Qt::OpaqueMode且pen()为点画时,background()才适用。在这种情况下,它描述点画中背景像素的颜色。
    brushOrigin()定义平铺笔刷的原点,通常是小部件背景的原点。
    viewport()、window()、worldTransform()组成了画家的坐标变换系统。有关详细信息,请参见“坐标变换”部分和坐标系文档。
    hasClipping()告诉画家是否会剪辑(绘制设备也会剪辑。)如果绘制者剪辑,它会剪辑到clipRegion()。
    layoutDirection()定义画师绘制文本时使用的布局方向。
    worldMatrixEnabled()指示是否启用了世界转换。
    viewTransformEnabled()指示是否启用视图转换。

    ?

    请注意,其中一些设置镜像了某些绘制设备中的设置,例如QWidget::font()。QPainter::begin()函数(或等效的QPainter构造函数)从绘制设备复制这些属性。
    您可以随时通过调用save()函数保存QPainter的状态,该函数将保存内部堆栈上的所有可用设置。restore()函数将它们弹出。

    ?

    绘图
    qPaint提供了绘制大多数基本体的函数:drawPoint()、drawPoints()、drawLine()、drawRect()、drawRoundedRect()、drawAllipse()、drawArc()、drawPie()、drawChord()、drawPolyline()、drawPolygon()、drawConvexPolygon()和drawCubicBezier()。两个方便的函数drawRects()和drawrines()使用当前画笔在给定的QRects或qline数组中绘制给定数量的矩形或直线。


    QPainter类还提供fillRect()函数,该函数用给定的QBrush填充给定的QRect,并提供eraseRect()函数,该函数擦除给定矩形内的区域。


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

    ?

    如果需要绘制复杂形状,尤其是需要重复绘制,请考虑创建QPainterPath并使用drawPath()绘制它。

    ?

    QPainter还提供fillPath()函数,该函数用给定的QBrush填充给定的QPainterPath,并提供strokePath()函数,该函数绘制给定路径的轮廓(即,笔划路径)。
    另请参见向量变形示例,该示例演示如何使用高级向量技术使用QPainterPath绘制文本,渐变示例显示Qt中可用的不同类型渐变,路径笔划示例显示了Qt的内置破折号模式,并显示了如何使用自定义模式来扩展可用模式的范围。

    ?

    文本绘制是使用drawText()完成的。当需要细粒度定位时,boundingRect()会告诉您给定的drawText()命令将在何处绘制。
    绘制像素图和图像
    有一些函数可以绘制pixmap/images,即drawPixmap()、drawImage()和drawTilledPixmap()。drawPixmap()和drawImage()产生相同的结果,只是drawPixmap()在屏幕上更快,而drawImage()在QPrinter或其他设备上可能更快。
    有一个drawPicture()函数可以绘制整个QPicture的内容。drawPicture()函数是唯一一个忽略画家所有设置的函数,因为QPicture有自己的设置。
    绘制像素地图和图像的高分辨率版本
    高分辨率版本的pixmap的设备像素比率值大于1(请参阅QImageReader,QPixmap::devicePixelRatio())。如果它与基础QPaintDevice的值匹配,则直接将其绘制到设备上,而不应用其他转换。
    例如,将设备像素比为2的64x64像素大小的QPixmap绘制到同样具有设备像素比2的高DPI屏幕上时的情况。注意,pixmap在用户空间中实际上是32x32像素。Qt中基于pixmap大小计算布局几何图形的代码路径将使用此大小。这样做的净效果是pixmap显示为高DPI pixmap,而不是大pixmap。
    渲染质量
    为了使用QPainter获得最佳的渲染效果,应该使用平台无关的QImage作为绘制设备;i、 e.使用QImage将确保结果在任何平台上具有相同的像素表示。
    QPainter类还通过RenderHint enum和对浮点精度的支持提供了一种控制渲染质量的方法:所有用于绘制原语的函数都有一个浮点版本。它们通常与QPainter::Antialiasing render提示结合使用。

    ?

    ?

    RenderHint enum指定QPainter的标志,任何给定的引擎都可能遵循这些标志,也可能不遵循这些标志。QPainter::Antialiasing表示引擎应尽可能对基本体的边进行反锯齿,QPainter::TextAntialiasing表示引擎应尽可能对文本进行反锯齿,QPainter::SmoothPixmapTransform表示引擎应使用平滑pixmap变换算法。
    函数的作用是:返回一个标志,用于指定为此绘制程序设置的渲染提示。使用setRenderInt()函数设置或清除当前设置的RenderInt。
    坐标变换
    通常,QPainter在设备自己的坐标系(通常是像素)上操作,但是QPainter对坐标变换有很好的支持。

    ?

    ?

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

    ?

    ?

    所有的转换操作都在transformation worldTransform()上操作。矩阵将平面上的一点变换为另一点。有关变换矩阵的详细信息,请参见坐标系和QTransform文档。
    setWorldTransform()函数可以替换或添加到当前设置的worldTransform()。resetTransform()函数用于重置使用translate()、scale()、shear()、rotate()、setWorldTransform()、setViewport()和setWindow()函数进行的所有变换。deviceTransform()返回矩阵,该矩阵将依赖于平台的绘制设备的逻辑坐标转换为设备坐标。只有在平台相关句柄上使用平台绘制命令时才需要后一个函数,并且平台本身不进行转换。
    在使用QPainter绘制时,我们使用逻辑坐标指定点,然后将这些坐标转换为绘制设备的物理坐标。逻辑坐标到物理坐标的映射由qpaint的combinedTransform()处理,它是viewport()和window()以及worldTransform()的组合。viewport()表示指定任意矩形的物理坐标,window()以逻辑坐标描述同一矩形,worldTransform()与变换矩阵相同。
    另请参见坐标系
    剪辑
    QPaint可以将任何绘图操作剪裁到矩形、区域或矢量路径。使用函数clipRegion()和clipPath()可以获得当前剪辑。路径或区域是否首选(更快)取决于基础paintEngine()。例如,QImage绘制引擎首选路径,而X11绘制引擎首选区域。设置剪辑是在画家的逻辑坐标中完成的。
    在油漆工裁剪之后,油漆装置也可以裁剪。例如,大多数小部件都会剪掉子部件使用的像素,大多数打印机会剪掉纸张边缘附近的区域。clipRegion()或hasClipping()的返回值不反映此附加剪辑。
    合成模式
    QPainter提供CompositionMode enum,定义用于数字图像合成的Porter-Duff规则;它描述了一个模型,用于将一个图像(源)中的像素与另一个图像(目标)中的像素相结合。
    最常见的两种构图形式是Source和SourceOver。源用于在绘制设备上绘制不透明对象。在这种模式下,源中的每个像素将替换目标中相应的像素。在SourceOver合成模式中,源对象是透明的,并且绘制在目标对象的顶部。
    注意,合成变换是按像素操作的。因此,使用图形原语本身和它的边界矩形之间有区别:边界矩形包含alpha==0的像素(即原语周围的像素)。这些像素将覆盖另一个图像的像素,有效地清除这些像素,而原语只覆盖其自己的区域。

    ?

    局限性
    如果您使用的坐标与Qt的光栅为基础的绘画引擎,重要的是要注意的是,虽然坐标大于+/-215可以使用,任何绘画执行的坐标以外的这一范围是不能保证显示;这幅画可以剪掉。这是由于在实现中使用了short int。
    Qt的stroker生成的轮廓在处理曲线形状时只是一个近似值。在大多数情况下,不可能用另一个bezier曲线段来表示bezier曲线段的轮廓,因此Qt用几个较小的曲线来近似曲线轮廓。出于性能原因,Qt对这些轮廓使用的曲线数量是有限制的,因此当使用较大的笔宽或刻度时,轮廓误差会增加。要生成错误较小的轮廓,可以使用QPainterPathStroker类,该类具有setCurveThreshold成员函数,让用户指定错误容忍度。另一种解决方法是先将路径转换为多边形,然后绘制多边形。
    性能
    QPainter是一个丰富的框架,允许开发人员进行各种各样的图形操作,例如渐变、合成模式和矢量图形。QPainter可以跨各种不同的硬件和软件堆栈来实现这一点。自然地,硬件和软件的基本组合对性能有一定的影响,并且确保每一个操作与构图模式、画笔、剪辑、变换等的所有不同组合的结合都是快速的,由于排列的数量,这几乎是不可能完成的任务。作为一个折衷方案,我们选择了QPainter API和后端的一个子集,在这里,性能保证尽可能好,因为对于给定的硬件和软件组合,我们可以合理地获得它。
    作为高性能发动机,我们关注的后端包括:
    光栅-此后端在纯软件中实现所有渲染,并始终用于渲染为QImages。为获得最佳性能,请仅使用格式类型QImage::format\u ARGB32\u Premultiplied、QImage::format\u RGB32或QImage::format\u RGB16。任何其他格式,包括QImage::format\u ARGB32,性能都要差得多。这个引擎默认用于QWidget和QPixmap。
    OpenGL 2.0(ES)-此后端是硬件加速图形的主要后端。它可以在支持opengl2.0或OpenGL/es2.0规范的台式机和嵌入式设备上运行。这包括过去几年生产的大多数图形芯片。可以通过在QOpenGLWidget上使用QPaint启用引擎。
    这些操作包括:
    简单的变换,意味着平移和缩放,加上0,90,180,270度旋转。
    drawPixmap()与简单变换和不透明度结合使用的非平滑变换模式(qPaint::SmoothPixmapTransform未作为渲染提示启用)。
    矩形填充纯色、双色线性渐变和简单变换。
    矩形剪辑与简单的变换和相交剪辑。
    合成模式QPainter::CompositionMode\u Source和QPainter::CompositionMode\u SourceOver
    圆角矩形填充使用纯色和双色线性渐变填充。
    3x3拼接像素地图,通过qDrawBorderPixmap。
    此列表指示在性能至关重要的应用程序中安全使用哪些功能。对于某些设置,其他操作可能也很快,但在广泛使用它们之前,建议在最终运行软件的系统上对它们进行基准测试和验证。也有一些情况下,可以使用昂贵的操作,例如当结果缓存在QPixmap中时。


    另请参见QPaintDevice、QPaintEngine、Qt SVG、基本绘图示例和绘图实用程序函数。

    ?

    下一篇:没有了