【Qt开发流程】之2D绘图1:概述及基本绘制与填充和渐变填充

2023-12-13 03:47:35

概述

Qt的绘图系统可以使用相同的API在屏幕和打印设备上进行绘图,并且主要基于QPainter, QPaintDeviceQPaintEngine类。
QPainter用于执行绘图操作,QPaintDevice是一个二维空间的抽象,可以使用QPainter在其上绘制,QPaintEngine提供了QPainter用于在不同类型的设备上绘制的接口。QPaintEngine类在QPainterQPaintDevice内部使用,并且对应用程序程序员是隐藏的,除非他们创建自己的设备类型。

这种方法的主要好处是,所有的绘制都遵循相同的绘制方式,从而很容易添加对新特性的支持,并为不支持的特性提供默认实现。

以下类为QPainter绘制提供了支持:

描述
QBitmap单色(1位深度)像素图
QBrush定义由QPainter绘制的形状的填充模式
QColor基于RGB, HSV或CMYK值的颜色
QColormap将与设备无关的QColors映射到与设备相关的像素值
QConicalGradient与QBrush结合使用,指定锥形梯度刷
QFont指定用于绘制文本的字体
QFontMetrics字体度量信息
QFontMetricsF字体度量信息
QGenericMatrix模板类,表示有N列和M行的NxM变换矩阵
QGradient与QBrush结合使用来指定渐变填充
QIcon不同模式和状态下的可伸缩图标
QIconEngineQIcon渲染器的抽象基类
QImage独立于硬件的图像表示,允许直接访问像素数据,并且可以用作绘画设备
QImageReader格式独立的接口,读取图像从文件或其他设备
QImageWriter用于将图像写入文件或其他设备的格式独立接口
QLine二维矢量采用整数精度
QLineF二维矢量使用浮点精度
QLinearGradient与QBrush结合使用,指定线性梯度刷
QMargins定义矩形的四个边距
QMarginsF定义矩形的四个边距
QPagedPaintDevice表示支持多个页面的绘图设备
QPaintDevice可以用QPainter绘制的对象的基类
QPaintEngineQPainter如何在给定平台上绘制给定设备的抽象定义
QPainter在小部件和其他绘制设备上执行低级绘制
QPainterPath用于绘制操作的容器,使图形形状能够被构造和重用
QPainterPathStroker用于为给定的画家路径生成可填充的轮廓
QPdfWriter类生成可用作绘图设备的pdf
QPen定义QPainter应该如何绘制形状的线条和轮廓
QPixmap可以用作绘画设备的屏幕外图像表示
QPlatformFontDatabase可以自定义字体的发现方式和呈现方式
QPoint使用整数精度在平面上定义一个点
QPointF使用浮点精度在平面上定义一个点
QPolygon向量点使用整数精度
QPolygonF向量点使用浮点精度
QRadialGradient与QBrush结合使用,指定径向梯度刷
QRect使用整数精度在平面上定义一个矩形
QRectF使用浮点精度在平面中定义一个矩形
QRegion指定绘图器的剪辑区域
QSize使用整数点精度定义二维对象的大小
QSizeF使用浮点精度定义二维对象的大小
QStylePainter用于在小部件内绘制QStyle元素的方便类
QSupportedWritingSystems在使用内部Qt字体数据库注册字体时使用
QSvgGenerator用于创建SVG绘图的绘图设备
QSvgRenderer用于将SVG文件的内容绘制到绘图设备上
QSvgWidget小部件,用于显示可缩放矢量图形(SVG)文件的内容
QTransform指定坐标系统的2D转换
QVector2D表示二维空间中的向量或顶点

创建绘画设备

QPaintDevice类是可以绘制对象的基类,也就是说,QPainter可以在任何QPaintDevice子类上绘制。QPaintDevice的绘图功能是由QWidgetQImageQPixmapQPictureQPrinterQOpenGLPaintDevice实现的。

Widget

QWidget类是Qt Widgets模块中用户界面元素的基类。它接收来自窗口系统的鼠标、键盘和其他事件,并在屏幕上描绘自己的表示。

Image

QImage类提供了一个独立于硬件的图像表示,它是为I/O和直接的像素访问和操作而设计和优化的。QImage支持多种图像格式,包括单色,8位,32位和alpha混合图像。
使用QImage作为绘图设备的一个优点是,它可以以与平台无关的方式保证任何绘图操作的像素准确性。另一个好处是,绘制可以在当前GUI线程之外的另一个线程中执行。

Pixmap

QPixmap类是一个屏幕外的图像表示,它被设计和优化为在屏幕上显示图像。与QImage不同,像素图中的像素数据是内部的,由底层窗口系统管理,即像素只能通过QPainter函数或将QPixmap转换为QImage来访问。
为了使用QPixmap优化绘图,Qt提供了QPixmapCache类,它可以用于存储生成昂贵的临时像素图,而不会使用超过缓存限制的存储空间。
Qt还提供了QBitmap便利类,继承了QPixmapQBitmap保证单色(1位深度)像素图,主要用于创建自定义QCursorQBrush对象,构造QRegion对象。

OpenGL绘制设备

如前所述,Qt提供了一些类,使在Qt应用程序中使用OpenGL变得很容易。例如,QOpenGLPaintDevice启用OpenGL API来Picture
QPicture类是一个记录和回放QPainter命令的绘图设备。图片以平台无关的格式将画工命令序列化到IO设备。QPicture也是独立于分辨率的,即一个QPicture可以显示在不同的设备上(例如svg, pdf, ps,打印机和屏幕),看起来是一样的。
Qt提供了QPicture::load()QPicture::save()函数以及用于加载和保存图片的流操作符。

Custom Backends

可以通过派生QPaintDevice类并重新实现虚拟QPaintDevice:: paintenengine()函数来实现对新后端的支持,以告诉QPainter应该使用哪个绘制引擎在这个特定的设备上绘制。要真正能够在设备上绘图,这个绘图引擎必须是从qpaintenengine类派生出来的自定义绘图引擎。

绘制

QPainter提供了高度优化的功能,以完成大多数绘图GUI程序所需的功能。它可以绘制从简单的图形基元(由QPoint, QLine, QRect, QRegion和QPolygon类表示)到复杂形状(如矢量路径)的一切。在Qt矢量路径是由QPainterPath类表示的。QPainterPath为绘制操作提供了一个容器,使图形形状能够被构造和重用。

QPainterPath

painter路径是由线条和曲线组成的对象。例如,矩形由直线组成,椭圆由曲线组成。
与普通绘图操作相比,绘制路径的主要优势在于,复杂的形状只需要创建一次;然后只需调用QPainter::drawPath()函数就可以多次绘制它们。
QPainterPath对象可用于填充、勾勒和裁剪。要为给定的painter路径生成可填充的轮廓,可以使用QPainterPathStroker类。
线条和轮廓是使用QPen类绘制的。pen由其样式(即线条类型)、宽度、笔刷、如何绘制端点(cap-style)以及如何绘制两条连接线之间的连接(join-style)来定义。pen的笔刷是一个QBrush对象,用来填充pen生成的笔画,也就是说,QBrush类定义了填充模式。
QPainter还可以绘制对齐的文本和像素图。
绘制文本时,使用QFont类指定字体。Qt将使用具有指定属性的字体,或者如果没有匹配的字体存在,Qt将使用最接近匹配的已安装字体。实际使用的字体属性可以使用QFontInfo类检索。此外,QFontMetrics类提供字体度量,QFontDatabase类提供有关底层窗口系统中可用字体的信息。
通常,QPainter在“自然”坐标系中绘制,但它能够使用QTransform类执行视图和世界坐标系转换。

反锯齿绘制

绘制时,像素渲染由QPainter::Antialiasing渲染提示控制。QPainter::RenderHint枚举用于指定QPainter的标志,这些标志可能被任何给定的引擎尊重,也可能不被尊重。
QPainter::Antialiasing值表示引擎应该尽可能地消除原语的边缘,即通过使用不同的颜色强度平滑边缘。

基本图形绘制、填充

绘制线

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter p(this);
    p.drawLine(50, 50, 100, 150);
}

在这里插入图片描述
或者,创建时不指定绘制设备,在begin()函数中设置,end时结束绘制。

    QPainter p;
    p.begin(this);
    p.drawLine(50, 50, 100, 150);
    p.end();

绘制圆弧
绘制由给定矩形、startAngle和spanAngle定义的圆弧。
起始角和伸缩角必须以1/16度指定,即一个完整的圆等于5760(16 * 360)。角度的正值表示逆时针方向,负值表示顺时针方向。零度在3点钟方位。

    QPainter p;
    p.begin(this);
    QRectF rectangle(10.0, 20.0, 80.0, 60.0);
    int startAngle = 30 * 16;
    int spanAngle = 120 * 16;
    p.drawArc(rectangle, startAngle, spanAngle);
    p.end();

在这里插入图片描述
绘制弦
绘制由给定矩形、startAngle和spanAngle定义的弦。弦被当前的笔刷()填充。
起始角和伸缩角必须以1/16度指定,即一个完整的圆等于5760(16 * 360)。角度的正值表示逆时针方向,负值表示顺时针方向。零度在3点钟方位。

    QPainter p;
    p.begin(this);
    QRectF rectangle(10.0, 20.0, 80.0, 60.0);
    int startAngle = 30 * 16;
    int spanAngle = 120 * 16;
    p.drawChord(rectangle, startAngle, spanAngle);
    p.end();

在这里插入图片描述
绘制凸多边形

    QPainter p;
    p.begin(this);
    static const QPointF points[4] = {
        QPointF(40.0, 110.0),
        QPointF(50.0, 40.0),
        QPointF(110.0, 70.0),
        QPointF(120.0, 100.0)
    };
    p.drawConvexPolygon(points, 4);
    p.end();

在这里插入图片描述
绘制椭圆

    QPainter p;
    p.begin(this);
    QRectF rectangle(100.0, 50.0, 80.0, 60.0);

    p.drawEllipse(rectangle);
    p.end();

在这里插入图片描述
如果宽,高一样,就是圆。
绘制扇形

    QPainter p;
    p.begin(this);
    QRectF rectangle(100.0, 50.0, 160.0, 120.0);
    int startAngle = 30 * 16;
    int spanAngle = 120 * 16;

    p.drawPie(rectangle, startAngle, spanAngle);
    p.end();

在这里插入图片描述

填充

除此之外,还可以使用画笔及画刷进行绘制和填充
绘制多边形

    QPainter p;
    p.begin(this);
    QPen pen(QBrush(Qt::gray), 2, Qt::DashLine, Qt::FlatCap, Qt::RoundJoin);
    p.setPen(pen);

    p.setBrush(Qt::green);

    static const QPointF points[4] = {
        QPointF(40.0, 110.0),
        QPointF(50.0, 40.0),
        QPointF(110.0, 70.0),
        QPointF(120.0, 100.0)
    };
    p.drawPolygon(points, 4);
    p.end();

在这里插入图片描述
绘制圆角矩形

    QPainter p;
    p.begin(this);
    QPen pen(QBrush(Qt::black), 2, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin);
    p.setPen(pen);

    p.setBrush(Qt::lightGray);

    QRectF rectangle(10.0, 20.0, 80.0, 60.0);

    p.drawRoundedRect(rectangle, 20.0, 15.0);
    p.end();

在这里插入图片描述

渐变填充

使用画刷还可以进行渐变填充。
渐变有三种:

  • 线性渐变:QLinearGradient
  • 辐射渐变:QRadialGradient
  • 锥形渐变:QConicalGradient

在这里插入图片描述
绘制矩形

    QPainter p;
    p.begin(this);
    QPen pen(QBrush(Qt::black), 2, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin);
    p.setPen(pen);

    QLinearGradient linearGrad(QPointF(100, 100), QPointF(200, 200));
    linearGrad.setColorAt(0, Qt::black);
    linearGrad.setColorAt(1, Qt::white);
    p.setBrush(linearGrad);

    QRectF rectangle(100.0, 100.0, 100.0, 100.0);

    p.drawRoundedRect(rectangle, 20.0, 15.0);
    p.end();

在这里插入图片描述

结论

人生就是这样,有欢笑也有泪水。一部分人主要负责欢笑,另一部分人主要负责泪水

文章来源:https://blog.csdn.net/MrHHHHHH/article/details/134938849
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。