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

概述

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();

在这里插入图片描述

结论

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/239739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis核心配置文件加载流程详解

Mybatis核心配置文件加载流程详解 本文将介绍MyBatis在配置文件加载的过程中,如何加载核心配置文件、如何解析映射文件中的SQL语句以及每条SQL语句如何与映射接口的方法进行关联。 映射配置文件 在介绍核心配置文件加载流程前,先给出一个简单的MyBati…

从概念到现实,2024中国式元宇宙如何落地?

前几个月,马斯克和扎克伯格隔空约架愈演愈烈,网友拱火也其乐无穷。两位顶级富豪贴身肉搏? 想想就刺激! 随之,老马的X(原Twitter)和小扎的Threads(X竞品)也获得了颇多关注…

为什么看书或者看文章有时候晕?

我今天发现,当我看了一篇深度学习相关的文章(我是0基础机器学习) 当我尝试理解的时候,头就开始晕了(也有些人是犯困),并不是你的错,而是因为看不懂。 仔细观察就发现,看…

Python从入门到精通九:Python异常、模块与包

了解异常 什么是异常 当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”, 也就是我们常说的BUG bug单词的诞生 早期计算机采用大量继电器工作,马克二型计算机就是这样的。 19…

Java实现插入排序及其动图演示

插入排序是一种简单直观的排序算法。它的基本思想是将一个待排序的元素插入到已经排序好的序列中的适当位置,从而得到一个新的、元素个数加一的有序序列。 具体的插入排序算法过程如下: 从第一个元素开始,认为第一个元素已经是有序序列。取…

Jmeter场景设置与监听

Jmeter场景设置 场景的概念: 场景是用来尽量真实模拟用户操作的工作单元,场景设计源自于用户真实操作。 场景设计: 场景设计是根据收集分析用户的实际操作而定义的Jmeter脚本的执行策略。 性能测试中涉及的基本场景有两种,即单一业务场景和混合业务场景…

js 有关递归简单介绍

递归:指调用自身的函数 重点:递归函数必须有可以终止递归调用的语句,否则会导致内存溢出 递归的性能不好,因为在递归终止前,JavaScript引擎会为每一次递归分配一块内存以存储栈帧,随着递归的深入&#xff…

掌握 Python sympy 库的高级计算技巧

更多资料获取 📚 个人网站:ipengtao.com Sympy是Python中一个强大的符号计算库,为数学和科学计算提供了丰富的功能。本文将深入介绍Sympy库的各项功能,并提供丰富的示例代码,以帮助大家更好地理解和应用这一工具。 S…

网络基础(七):传输层协议介绍

目录 一、TCP协议(传输控制协议) 1、TCP协议介绍 2、TCP协议特性 3、TCP报文格式 4、TCP的三次握手 4.1TCP三次握手的概念 4.2TCP三次握手流程图 4.3 TCP三次握手阐释说明 5、TCP的四次挥手 5.1TCP四次挥手的概念 5.2TCP四次挥手的流程图 5.…

阿里云服务器ECS安全组开启端口教程

阿里云服务器安全组开启端口教程 云服务器 ECS(Elastic Compute Service) 云服务器 ECS(Elastic Compute Service)是一种安全可靠、弹性可伸缩的云计算服务,助您降低 IT 成本,提升运维效率,使您…

【OPENGIS】Geoserver升级Jetty,不修改java版本

昨天搞了一个geoserver升级9.4.53版本的方法,但是需要修改java的版本,因为jetty官方网站下载的jar包是用jdk11编译的,如果不升级java版本,运行就会报错。 可是现场环境限制比较多,升级了java版本之后有些老版本的程序又…

0基础学习VR全景平台篇第126篇:嵌入视频前期拍摄要点及后期处理

上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 一、前期拍摄要点 嵌入视频的简介和用途 livepano即完全无缝融合到全景图中的热点嵌入视频。 这种无缝融合是真正无缝,从而让观者产生沉浸感和真实感。例如在场景中…

第 6 部分 — 对 LLM 的对抗性攻击。数学和战略分析

第 6 部分 — 对 LLM 的对抗性攻击。数学和战略分析 一、说明 针对大型语言模型(LLM)的对抗性攻击代表了人工智能安全中一个复杂的关注领域,需要数学严谨性和战略远见的复杂结合。这些攻击旨在操纵 LLM 产生意想不到的输出,范围从…

Android studio:打开应用程序闪退的问题2.0

目录 找到问题分析问题解决办法 找到问题 老生常谈,可能这东西真的很常见吧,在之前那篇文章中 linkhttp://t.csdnimg.cn/UJQNb 已经谈到了关于打开Androidstuidio开发的软件后明明没有报错却无法运行(具体表现为应用程序闪退的问题&#xff…

学习深度强化学习---第2部分----RL动态规划相关算法

文章目录 2.1节 动态规划简介2.2节 值函数与贝尔曼方程2.3节 策略评估2.4节 策略改进2.5节 最优值函数与最优策略2.6节 值迭代与策略迭代2.7节 动态规划求解最优策略 本部分视频所在地址:深度强化学习的理论与实践 2.1节 动态规划简介 态规划有两种思路&#xff1…

Linux(20):软件安装:原始码与 Tarball

开放源码的软件安装与升级 在Windows系统上面的软件都是一模一样的,【无法修改该软件的源代码】,因此,万一想要增加或者减少该软件的某些功能时,无能为力。。。 Linux 上面的软件几乎都是经过 GPL 的授权,所以每个软件…

Conda使用教程

文档 老规矩,先上官方文档链接 Anaconda Distribution — Anaconda documentation 是什么 anaconda是python环境管理工具。当需要用到多个python版本时,使用anaconda可以方便快速地进行环境切换,依赖包的安装。底层原理是修改环境变量。 …

C++核心编程——多态与虚函数

C核心编程——多态与虚函数 多态的概念一个典型例子利用虚函数实现动态多态性虚函数的作用虚析构函数 纯虚函数与抽象类 多态的概念 在面向对象方法中一般是这样表述多态性的:向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。…

渲染农场对工业产品渲染带来的意义与优势?

随着科技的进步,利用精细渲染图来呈现和推广工业设计的创新已成为行业标准。这些图像在产品研发、设计评审和营销阶段起着关键作用,同时对产品最终的成功也产生深远影响。然而,由于产品设计日渐复杂,制作渲染图的任务变得极具挑战…

VisualSVN Server的安装全过程

目录 背景: 安装过程: 步骤1: 步骤2: 步骤3: 步骤4: 步骤5: 安装出现的bug: 问题: 解决办法: 总结: 背景: VisualSVN Server 是一款免费的 SVN (Subversion) 服务器软件&#xff0c…