Qt:玩转QPainter序列一

news/2024/9/18 14:48:24/ 标签: qt, 开发语言

前言

最近想潜心研究一下QPainter这个类,最好把QPainter所有的函数都敲一遍,特地记录一下。
在说QPainter之前我们需要了解两个非常重要的东西

第一个坐标系

我用两张图来表示
在这里插入图片描述

代码实操的结果
在这里插入图片描述

更加详细的坐标系内容请看我的另一篇博客

第二个是有关绘图的一些基本概念

QPainter:Qt中的绘图类,用于在各种设备上进行绘图操作。
QPen:用于定义线条的颜色、宽度和样式。
QBrush:用于定义填充区域的颜色、渐变和图案。
QPixmap:用于表示位图图像。
QImage:用于表示图像,支持像素级别的操作。

正文

下面是QPainter的类定义开头一部分,我们逐行开始分析
在这里插入图片描述

1. 头文件保护符:

#ifndef QPAINTER_H
#define QPAINTER_H

这段代码用于防止头文件的重复包含。
#ifndef QPAINTER_H 是在检查 QPAINTER_H 是否未定义。
如果未定义,则使用 #define QPAINTER_H 来定义它。
这样当此文件被多次包含时,后续的包含将不会重复定义 QPAINTER_H,从而避免编译错误。

2. 头文件的包含:

#include <QtGui/qtguiglobal.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qrect.h>
#include <QtCore/qpoint.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qimage.h>
#include <QtGui/qtextoption.h>

这些 #include 指令用于将其他必要的头文件包含到当前文件中。

  • QtGui/qtguiglobal.h 包含与Qt GUI模块相关的全局定义。
  • QtCore/qnamespace.h 包含命名空间相关的定义。
  • qrect.hqpoint.h 是与几何对象相关的头文件,定义了矩形和点的类。
  • qscopedpointer.h 提供了智能指针的功能,用于内存管理。
  • qpixmap.hqimage.h 是处理图像和位图的类的头文件。
  • qtextoption.h 包含与文本显示选项相关的定义。

3. 条件性包含:

#ifndef QT_INCLUDE_COMPAT
#include <QtGui/qpolygon.h>
#include <QtGui/qpen.h>
#include <QtGui/qbrush.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qtransform.h>
#include <QtGui/qfontinfo.h>
#include <QtGui/qfontmetrics.h>
#endif

这部分代码表示,当 QT_INCLUDE_COMPAT 未定义时,才会包含这些头文件。
这些文件中包含了与多边形、画笔、刷子、矩阵变换、字体信息、字体度量等相关的类。

4. 命名空间开始:

QT_BEGIN_NAMESPACE

QT_BEGIN_NAMESPACE 是一个宏,用于标记Qt库的命名空间的开始。
它通常与 QT_END_NAMESPACE 搭配使用,用于确保在不同的编译环境中命名空间的正确使用。

这是下面一部分的定义,继续看
在这里插入图片描述

1. 前置声明(Forward Declarations):

class QBrush;
class QFontInfo;
class QFontMetrics;
class QPaintDevice;
class QPainterPath;
class QPainterPrivate;
class QPen;
class QPolygon;
class QTextItem;
class QTextEngine;
class QMatrix;
class QTransform;
class QStaticText;
class QGlyphRun;class QPainterPrivateDeleter;

这些是类的前置声明。前置声明是告诉编译器这些类的名称和它们是类类型,而不提供它们的完整定义。
这样做的目的是提高编译效率,避免包含不必要的头文件。
在需要使用这些类的指针或引用时,可以仅使用前置声明,而不需要完整的类定义。

2. 类的声明:

class Q_GUI_EXPORT QPainter{}

QPainter 是一个用来执行绘图操作的类。在Qt中,QPainter 类提供了绘制文本、图像、线条和其他图形元素的方法。

  • Q_GUI_EXPORT 是一个宏,用于导出这个类,使其在动态链接库(DLL)中可用。

3. 宏定义:

Q_DECLARE_PRIVATE(QPainter)
Q_GADGET
  • Q_DECLARE_PRIVATE(QPainter) 是一个宏,用于声明一个指向该类的私有数据指针 d_ptr。这是Qt中常用的一个设计模式,用来实现Pimpl(Pointer to Implementation)技术,分离接口和实现,增强封装性。

  • Q_GADGET 是一个用于声明轻量级的Qt对象的宏。虽然它不像 QObject 那样支持信号和槽,但它可以使用元对象系统的其他功能,比如枚举的元信息。

4. 公共部分 (public):

public:enum RenderHint {Antialiasing = 0x01,TextAntialiasing = 0x02,SmoothPixmapTransform = 0x04,
#if QT_DEPRECATED_SINCE(5, 14)HighQualityAntialiasing Q_DECL_ENUMERATOR_DEPRECATED_X("Use Antialiasing instead") = 0x08,NonCosmeticDefaultPen Q_DECL_ENUMERATOR_DEPRECATED_X("Default pen is non-cosmetic now") = 0x10,
#endifQt4CompatiblePainting = 0x20,LosslessImageRendering = 0x40,};

public 表示这一部分的成员可以被类的外部访问。

  • RenderHintQPainter 类中的一个枚举类型,用于指定绘图时的渲染提示。渲染提示是一些位掩码值,用于控制绘图的质量和性能。

    • Antialiasing = 0x01:启用抗锯齿,以获得平滑的图形边缘。
    • TextAntialiasing = 0x02:启用文本的抗锯齿处理。
    • SmoothPixmapTransform = 0x04:启用平滑的位图变换。

    枚举中还包括一些已弃用的选项,用 QT_DEPRECATED_SINCE(5, 14) 来标记。

    • HighQualityAntialiasing:高质量抗锯齿处理,但已弃用,建议使用 Antialiasing 代替。
    • NonCosmeticDefaultPen:默认笔非装饰性,但已弃用。

    其他选项:

    • Qt4CompatiblePainting = 0x20:启用与Qt 4兼容的绘图模式。
    • LosslessImageRendering = 0x40:启用无损图像渲染,确保图像质量。

OK现在我们写一个小例子来测试这些渲染

void PlayQPainter::paintEvent(QPaintEvent *event)
{QPainter painter(this);// 设置当前的渲染提示//painter.setRenderHint(QPainter::Antialiasing,true);// 绘制不同的图形以展示渲染效果painter.drawEllipse(50, 50, 200, 200);  // 画圆painter.drawText(100, 300, "没有开始渲染时的效果!");  // 画文本// 绘制图像(假设有一个图像)painter.drawPixmap(50, 350, QPixmap("D:/all_the_code/qt_code/ts/playQPainter/lyf.jpg"));// 测试其他几何图形painter.drawRect(300, 50, 200, 200);  // 画矩形painter.drawLine(550, 50, 580, 580);  // 画线条
}

在这里插入图片描述
没有开启渲染时可以看到线条有许多锯齿状

void PlayQPainter::paintEvent(QPaintEvent *event)
{QPainter painter(this);// 设置当前的渲染提示painter.setRenderHint(QPainter::Antialiasing,true);// 绘制不同的图形以展示渲染效果painter.drawEllipse(50, 50, 200, 200);  // 画圆painter.drawText(100, 300, "开启平滑抗锯齿时的效果!");  // 画文本// 绘制图像(假设有一个图像)painter.drawPixmap(50, 350, QPixmap("D:/all_the_code/qt_code/ts/playQPainter/lyf.jpg"));// 测试其他几何图形painter.drawRect(300, 50, 200, 200);  // 画矩形painter.drawLine(550, 50, 580, 580);  // 画线条
}

在这里插入图片描述
可以看到线条平滑了许多

void PlayQPainter::paintEvent(QPaintEvent *event)
{QPainter painter(this);QFont font;font.setPointSize(20);painter.setFont(font);// 设置当前的渲染提示painter.setRenderHint(QPainter::TextAntialiasing,true);// 绘制不同的图形以展示渲染效果painter.drawEllipse(50, 50, 200, 200);  // 画圆painter.drawText(100, 300, "开启文本抗锯齿时的效果!");  // 画文本// 绘制图像(假设有一个图像)painter.drawPixmap(50, 350, QPixmap("D:/all_the_code/qt_code/ts/playQPainter/lyf.jpg"));// 测试其他几何图形painter.drawRect(300, 50, 200, 200);  // 画矩形painter.drawLine(550, 50, 580, 580);  // 画线条
}

在这里插入图片描述
使用文本抗锯齿对文本影响很小,至少在我这边运行时是这样。
平滑位图变换我就不测试了,它是要用QImage来加载图片,而不是用QPainter来加载


http://www.ppmy.cn/news/1516982.html

相关文章

VCTP(Visual Chain-of-Thought Prompting for Knowledge-Based Visual Reasoning)论文

目录 摘要介绍相关工作方法总体模型细节 实验 摘要 知识型视觉推理仍然是一个艰巨的任务&#xff0c;因为它不仅要求机器从视觉场景中解释概念和关系&#xff0c;而且还需要将它们与外部世界知识联系起来&#xff0c;对开放世界问题进行推理链。然而&#xff0c;以前的工作将视…

【区块链 + 智慧文旅】鲜檬内容生态平台 | FISCO BCOS应用案例

基于鲜檬&#xff08;虎彩集团旗下的“鲜檬摄影有限公司”&#xff0c;简称鲜檬&#xff09;的业务规划&#xff0c;除了婚拍摄影外&#xff0c;以定制化家纺、 餐具、陶瓷品为主的产品诉求也日渐增加。为了支撑庞大的业务体量&#xff0c;设计能力的连接和整合迫在眉睫。同时&…

[C++番外] 抛异常

一、C语言的时候我们怎么判断错误的呢&#xff1f; C语言的错误处理机制&#xff1a; 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查…

如何下载jmeter旧版本

如何下载jmeter旧版本 推荐先用旧版本做好测试基本操作&#xff0c;因为高版本不适合做压力测试&#xff0c;需要证书&#xff0c;有点麻烦。 1.百度或直接打开jmeter官网&#xff1a;https://jmeter.apache.org/ 2.向下拖到Archives一栏&#xff0c;点击Apache Jmeter archi…

SpringCache源码解析(一)-Annotation

〇、常用注解 包地址注解名作用域作用org.springframework.cache.annotationCacheConfig类级别s设置缓存的公共配置Cacheable方法级别缓存读取操作CacheEvict方法级别缓存失效操作CachePut方法级别缓存更新操作Caching方法级别h混合读取、失效、更新操作CacheConfig方法级别统…

springboot-从0开始创建一个starter

创建一个Spring Boot Starter是一个很好的方式来封装常用的配置和依赖&#xff0c;以便在多个项目中重用。以下是一个简单的指南&#xff0c;教你如何开发一个自己的Spring Boot Starter。 一、创建步骤 1. 创建项目 首先&#xff0c;你需要创建一个Maven或Gradle项目。这里我…

QMT量化+通道快速,完美结合应对市场!

关注韭菜修养&#xff08;同名全拼音&#xff09;&#xff0c;投资道路我们一起成长&#xff01;第一&#xff1a;国内的量化交易软件众多&#xff0c;我们可以参考这几个维度①全内存极速交易&#xff1a;全内存交易&#xff0c;单笔延时&#xff1c;1ms满足量化高频交易客户对…

谷粒商城实战笔记-249-商城业务-消息队列-RabbitMQ工作流程

文章目录 一&#xff0c;基本概念二&#xff0c;消息从producer到consumer的过程 一&#xff0c;基本概念 RabbitMQ是一个流行的开源消息代理软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;。以下是RabbitMQ的一些基本概念&#xff1a; Broker&#x…

3 pytest Fixture

目录 3.1 通过 conftest.py 共享 fixture3.2 使用 fixture 执行配置及销毁逻辑3.3 使用 --setup-show 回溯 fixture 的执行过程3.4 使用 fixture 传递测试数据3.5 使用多个 fixture3.6 指定 fixture 作用范围3.7 使用 usefixtures 指定 fixture3.8 为常用 fixture 添加 autouse…

windows C++- WRL 使用计时器

由于WRL技术已经不作为主流继续发展&#xff0c;所以这里这个文档主要是收录WRL作为一些特殊情况下的查阅和理解windows体系开发的技术脉络&#xff0c;故本文档仅仅演示各项关键技术&#xff0c;例如本文档如何使用 Windows 运行时 C 模板库 (WRL) 启动异步操作并在操作完成时…

.ipynb文件:交互式 Jupyter Notebook

Python 接口文件&#xff08;带有扩展名的文件.pyi&#xff09;&#xff0c;或称为 Python 存根文件&#xff0c;在使用类型提示增强 Python 代码方面发挥着至关重要的作用。 当你遇到名称以 .ipynb、.pyi、.pyc 等结尾的 Python 文件时&#xff0c;你是否会感到困惑&#xff…

asp.net core在win上的发布和部署

一、asp.net core两种发布方式 1、两个发布方式——【框架依赖发布】和【独立发布】 2、两种发布方式的差别 二、发布的详细过程 1、【生成】->【发布】 2、框架依赖发布 设置发布参数&#xff0c;然后进行发布 发布好的文件&#xff0c;把它们放到一个新的目录文件夹里 …

LLaMA Factory微调Llama3模型

LLaMA Factory是一款开源低代码大模型微调框架&#xff0c;集成了业界最广泛使用的微调技术&#xff0c;支持通过Web UI界面零代码微调大模型&#xff0c;目前已经成为开源社区内最受欢迎的微调框架。 &#x1f4a5;GPU推荐使用24GB显存的A10&#xff08;ecs.gn7i-c8g1.2xlarg…

百度:未来or现在 顾此失彼?

用AI押注未来&#xff0c;却丢了现在 国内AI先行者百度 走到哪了&#xff1f; 作为这个星球最热门的概念&#xff0c;AI无疑是个好故事&#xff0c;不只是百度&#xff0c;美股的一众科技公司几乎都在讲述自己的AI投入及发展成果&#xff0c;市值也随着AI预期坐过山车。而市场…

css基础学习总结(一)

文章目录 一. 选择器1. 标签选择器2. 类选择器3. ID选择器4. 分组选择器5. 派生与子元素选择器6. 属性选择器7. 伪类选择器8. 伪对象选择器9. 选择器的优先级别css优先级 的 6大分类 一. 选择器 1. 标签选择器 选择器例子描述elementp/div/span选择所有含有指定标签的元素 &…

神经网络参数个数的计算

计算神经网络中参数的个数取决于网络的结构&#xff0c;包括层的类型和每层的节点数。以下是一些常见层类型的参数计算方法&#xff1a; 全连接层&#xff08;Fully Connected Layer&#xff09;&#xff1a; 参数个数 输入节点数 输出节点数 输出节点数&#xff08;偏置项…

什么是数据库 DevOps?

原文地址 https://www.bytebase.com/blog/what-is-database-devops/ 在深入研究数据库 DevOps 之前&#xff0c;先回顾一下什么是 DevOps。它没有统一的定义&#xff0c;但我们知道它起源于软件开发方法与部署和运维的结合。 大约 2007 年和 2008 年&#xff0c;软件开发和 I…

中国高校发表科技论文及著作数量数据集(2009-2022年)

中国各地区的高校科技产出数据&#xff0c;包括27个指标&#xff0c;科技论文发表、著作出版、专利申请、专利转让、国家标准项等。这些指标综合反映了各地区高校在科学研究和技术开发方面的活跃程度及创新能力 一、数据介绍 数据名称&#xff1a;中国地区高校发表科技论文、…

TCP/IP 协议:互联网的基石

TCP/IP 协议:互联网的基石 引言 TCP/IP协议,全称为传输控制协议/互联网协议(Transmission Control Protocol/Internet Protocol),是现代互联网通信的基础。自20世纪70年代末期以来,TCP/IP协议已经成为全球互联网通信的通用语言,它定义了数据如何在网络上进行传输和路由…

【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分

目录 一、做题心得 二、题目与题解 题目一&#xff1a;322. 零钱兑换 题目链接 题解&#xff1a;动态规划--完全背包 题目二&#xff1a; 279.完全平方数 题目链接 题解&#xff1a;动态规划--完全背包 题目三&#xff1a;139.单词拆分 题目链接 题解&#xff1a;动…