当前位置: 首页> 健康> 养生 > Qt:玩转QPainter序列一

Qt:玩转QPainter序列一

时间:2025/7/12 19:39:59来源:https://blog.csdn.net/m0_71489826/article/details/141439995 浏览次数:0次

前言

最近想潜心研究一下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来加载

关键字:Qt:玩转QPainter序列一

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: