首页 > 其他分享 >Qt开发:如何使用QPainter进行2D图形的绘制

Qt开发:如何使用QPainter进行2D图形的绘制

时间:2024-10-29 19:17:39浏览次数:8  
标签:Qt 填充 示例 2D 设置 绘制 QPainter

文章目录

一、QPainter简介

QPainter 是Qt框架中的一个强大的绘图类,用于在各种设备上进行 2D 图形绘制,例如窗口、图像、打印机等。QPainter 提供了丰富的 API,可以用来绘制形状、文本、图像以及其他图形对象,还支持高级特性,比如反锯齿、透明度、渐变填充等。绘图系统基于QPainter、QPaintDevice和QPaintEngine类,QPainter是用来绘图操作的类,QPaintDevice是一个可以使用QOPainter进行绘图的抽象的二维界面,QPaintEngine给QPainter提供在不同设备上绘图的接口。QPaintEngine类由QPainter和QPaintDevice内部使用,应用程序一般无需和QPaintEngine打交道,除非要创建自己的设备类型。一般的绘图设备包括QWidget、QPixmap、QImage等,这些绘图设备为QPainter提供一个画布。

二、如何使用QPainter绘图

使用QPainter绘图步骤:

  1. 需要继承QWidget,然后重写painEvent方法。
  2. 在重写的paintEvent方法中创建一个QPainter对象。
  3. 设置我们绘图中需要的参数,例如笔(QPen)、画刷(QBrush)、字体(QFont)等。
  4. 最后调用对应的方法去绘制我们想要的图像,如直接、三角形、矩形、圆形等。

那么我们为什么一定要在重写的painEvent方法中去绘制图形呢,而不是在其他地方绘制?

  1. 界面更新机制:当窗口被最小化、放大、还原或被其他窗口覆盖时,窗口内容可能会丢失,因此需要重绘。Qt 会自动触发 paintEvent 来重新绘制窗口内容,而不会漏掉任何刷新请求。这种机制避免了手动管理重绘的繁琐,同时保证绘图操作的统一性。
  2. 确保绘图的正确顺序:paintEvent 确保所有绘图内容按照先后顺序绘制。特别是当窗口部件有多个层次的绘制需求时,paintEvent 的绘制过程由 Qt 的绘制系统管理,从而避免了绘制冲突和不一致的问题。
  3. Qt 使用了“脏矩形”(dirty rectangle)更新策略,即仅重绘需要更新的区域。paintEvent 会自动接收到需要更新的区域(通过 QPaintEvent 的 region() 获取),这样可以提高效率,避免不必要的重绘和资源浪费。

三、QPainter的绘图区域

在这里插入图片描述
QWidget的绘制区域就是其窗口的内部区域,如上图所示,是在一个QWidget窗口上绘制了一个填充矩形。在整个窗口内部的矩形区就是QPainter可绘图的区域。QWidget的内部绘图区的坐标系统如上图所示,坐标系统的单位是像素,左上角坐标为(0, 0),向右是X轴正方向,向下是Y轴正方向,绘图区的宽度由QWidget::width()函数获取,高度由QWidget::height()函数获取,所以绘图区右下角的点坐标为(width(), height())。我们使用QPainter在绘图设备上绘图,主要绘制的是一些基本的图形元素,包括点、直线、圆形、矩形、曲线、文字等,控制这些绘图元素特性的主要是QPainter的三个属性。

  1. QPen:它主要用于控制线条的颜色、宽度、线型等。
  2. QBrush:用于设置一个区域的填充特性,可以设置填充颜色、填充方式、渐变特性等,还可以采用图片做材质填充。
  3. QFont:用于绘制文字时,设置文字的字体样式、大小属性等。

当然除了上述的三个基本的绘图属性,还有一些其他的功能结合,比如叠加模式、旋转和缩放等功能。

以下示例代码展示了如何使用 QPainter 绘制矩形:

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this); //创建与绘图设备关联的QPainter对象
    painter.setRenderHint(QPainter::Antialiasing); //启用反走样,使得绘图边缘更平滑,减少锯齿状边缘
    painter.setRenderHint(QPainter::TextAntialiasing); //启用文本反走样,改善文本渲染的质量
    QRect rect(this->width() / 4, this->height() / 4, this->width() / 2, this->height() / 2);

    QPen pen; //设置画笔
    pen.setWidth(3); //线宽
    pen.setColor(Qt::red); //划线颜色
    pen.setStyle(Qt::SolidLine); //线端点样式
    pen.setCapStyle(Qt::FlatCap); //线的样式,实践、虚线等
    pen.setJoinStyle(Qt::RoundJoin); //线的连接点样式
    painter.setPen(pen);

    QBrush brush;
    brush.setColor(Qt::yellow); //画刷颜色
    brush.setStyle(Qt::SolidPattern); //画刷填充样式
    painter.setBrush(brush);

    painter.drawRect(rect); //绘图

    QWidget::paintEvent(event);
}

四、QPainter的常用方法

QPainter支持基本图形绘制、文本绘制、图像绘制等多种功能,并包含了高级的绘制选项,比如反锯齿、透明度、渐变填充、坐标变换等。

基本形状的绘制:

drawLine():绘制直线。
drawRect():绘制矩形。
drawEllipse():绘制椭圆。
drawPolygon():绘制多边形。
drawPath():绘制复杂路径。

文本绘制:

drawText():在指定位置绘制文本,支持设置字体、颜色等属性。

图形绘制:

drawImage():在指定位置绘制QImage对象。
drawPixmap():绘制QPixmap,适用于显示图标等小图片。

设置绘制属性:

setPen():设置绘制线条的样式、颜色、宽度等。
setBrush():设置填充图形的画刷,可以时纯色、渐变色、纹理等。
setFont():设置文本绘制的字体。
setOpacity():设置透明度。

高级功能:

抗锯齿:通过setRenderHint(QPainter::Antialiasing, true)开启抗锯齿,以获取更平滑的绘制效果。
渐变填充:支持线性渐变、径向渐变和锥形渐变,可以使用QLinearGradient、QRadialGradient等来来实现。
坐标转换:QPainter提供了平移(translate())、旋转(rorate())和缩放(scale())等方法,可以方便的对绘制的内容进行几何变化。

五、QPen的主要功能和属性

QPen 是 Qt 中用于定义绘图线条样式的类,它控制线条的颜色、宽度、线型、连接风格、端点样式等。 QPen 通常用于 QPainter,可以自定义绘制图形的边框属性,使其绘图效果更灵活和丰富。

1.设置颜色 (color)
设置绘制线条的颜色,可以使用 QColor 或标准颜色名来指定,例如 Qt::black、QColor(255, 0, 0)。
示例:

pen.setColor(Qt::blue)

2.设置宽度 (width)
设置线条的宽度,以像素为单位。默认宽度为 1。
示例:

pen.setWidth(3)

3.设置线型 (style)
设置线条样式,可以选择实线、虚线、点线等。Qt::PenStyle 枚举提供了一些预定义的样。
示例:

pen.setStyle(Qt::DashLine)

Qt::SolidLine:实线
Qt::DashLine:虚线
Qt::DotLine:点线
Qt::DashDotLine:点划线
Qt::DashDotDotLine:双点划线

4.设置端点样式 (capStyle)
设置线条的端点样式(在绘制线段时起作用),即线条的起点和终点形状。
示例:

pen.setCapStyle(Qt::RoundCap)

Qt::SquareCap:方形端点
Qt::FlatCap:平直端点
Qt::RoundCap:圆形端点

5.设置连接样式 (joinStyle)
设置线段交汇处的连接样式(适用于折线等多段线的连接点)。

> Qt::MiterJoin:尖角连接
> Qt::BevelJoin:斜角连接
> Qt::RoundJoin:圆角连接

示例:
```cpp
pen.setJoinStyle(Qt::RoundJoin)

**6.设置虚线模式 (dashPattern)**
对于自定义虚线,可以通过 setDashPattern() 设置虚线的具体模式,传入一个 QVector<qreal> 来定义虚线和间隔的交替长度。
 示例:
```cpp
pen.setDashPattern({3, 5}); // 表示绘制3个像素线段,间隔5个像素。

下面是一个完整示例,展示如何创建并设置 QPen 以绘制不同风格的线条:

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    QPen pen;
    pen.setColor(Qt::red);
    pen.setWidth(5);
    pen.setStyle(Qt::DashDotLine);
    pen.setCapStyle(Qt::RoundCap);
    pen.setJoinStyle(Qt::RoundJoin);

    painter.setPen(pen);
    painter.drawLine(10, 10, 200, 10);

    // 绘制另一个线条
    pen.setColor(Qt::blue);
    pen.setStyle(Qt::DotLine);
    painter.setPen(pen);
    painter.drawLine(10, 30, 200, 30);

    QWidget::paintEvent(event);
}

在这里插入图片描述

六、QBrush的主要功能和属性

QBrush 是 Qt 中的填充工具类,用于定义图形的填充模式(即画刷样式),可填充纯色、渐变色、纹理、图案等。QBrush 在绘制形状时可以配合 QPainter 使用,以设置形状内部的填充效果。

1.设置填充颜色 (color)
QBrush 可以使用纯色填充图形区域。可以通过 QColor 或颜色名称(如 Qt::red)来定义填充颜色。
示例:

QBrush brush(Qt::blue)

2.设置填充样式 (style)
QBrush 提供了丰富的填充样式,
常用的样式包括:

Qt::SolidPattern:实心填充。
Qt::NoBrush:无填充,区域将保持透明。
Qt::Dense1Pattern 到 Qt::Dense7Pattern:不同密度的点状填充。
Qt::HorPattern / Qt::VerPattern:水平或垂直线条填充。
Qt::CrossPattern / Qt::DiagCrossPattern:十字交叉或对角交叉线条填充。
Qt::LinearGradientPattern、Qt::RadialGradientPattern、Qt::ConicalGradientPattern:渐变填充。

示例:

brush.setStyle(Qt::Dense4Pattern)

3.设置渐变填充 (QGradient)
QBrush 支持渐变色填充,可以创建线性渐变(QLinearGradient)、径向渐变(QRadialGradient)和锥形渐变(QConicalGradient)。可以设置渐变的起点、终点以及多种颜色,从而实现平滑的颜色过渡。
示例:

QLinearGradient gradient(0, 0, 100, 100);
gradient.setColorAt(0, Qt::red);
gradient.setColorAt(1, Qt::blue);
QBrush brush(gradient);

4.设置纹理填充 (QPixmap)
QBrush 支持使用图像纹理填充,即通过 QPixmap 对象指定纹理图案,可以将图案作为填充效果应用到图形上。
示例:

QPixmap texture(":/images/pattern.png");
QBrush brush(texture);

5.设置透明度
QBrush 的透明度可以通过 QColor 的 alpha 值或渐变的透明设置来控制,以创建半透明效果的填充。
示例:

QBrush brush(QColor(0, 255, 0, 128));  // 半透明绿色

以下示例展示了如何使用不同的 QBrush 填充样式绘制矩形和椭圆:

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    // 实心填充
    QBrush solidBrush(Qt::blue, Qt::SolidPattern);
    painter.setBrush(solidBrush);
    painter.drawRect(10, 10, 100, 100);

    // 渐变填充
    QLinearGradient gradient(0, 0, 100, 100);
    gradient.setColorAt(0, Qt::red);
    gradient.setColorAt(1, Qt::yellow);
    QBrush gradientBrush(gradient);
    painter.setBrush(gradientBrush);
    painter.drawEllipse(120, 10, 100, 100);

    // 纹理填充
    QPixmap texture("./cat.jpg");
    QBrush textureBrush(texture);
    painter.setBrush(textureBrush);
    painter.drawRect(230, 10, 100, 100);

    // 点状填充
    QBrush denseBrush(Qt::green, Qt::Dense3Pattern);
    painter.setBrush(denseBrush);
    painter.drawEllipse(350, 10, 100, 100);

    QWidget::paintEvent(event);
}

在这里插入图片描述

七、QFont的主要功能和属性

QFont 是 Qt 中用于设置文本字体的类,可以定义字体的家族、样式、大小等。它在绘制文本时通常与 QPainter 搭配使用,使开发者能够精确控制文本的外观。

1.设置字体家族 (family)
设置字体的家族名称,例如 “Arial”、“Times New Roman”、“Courier” 等,具体可选的字体家族取决于系统上已安装的字体。
示例:

font.setFamily("Arial")

2.设置字体大小 (pointSize 和 pixelSize)
字体大小可以通过点大小(point size)或像素大小(pixel size)来设置。setPointSize() 以点为单位,而 setPixelSize() 以像素为单位。
示例:

font.setPointSize(12);      // 设置字体为 12 点大小
font.setPixelSize(20);      // 设置字体为 20 像素大小

3.设置字体加粗 (bold)
通过设置 setBold(true) 可以使字体加粗。
示例:

font.setBold(true);

4.设置字体为斜体 (italic)
通过 setItalic(true) 将字体设置为斜体。
示例:

font.setItalic(true);

5.设置字体下划线 (underline)
通过 setUnderline(true) 在字体下方添加下划线。
示例:

font.setUnderline(true);

6.设置字间距 (letterSpacing)
设置字符之间的间距,可以通过 setLetterSpacing() 增加或减少字母之间的距离。常见单位为像素。
示例:

font.setLetterSpacing(QFont::AbsoluteSpacing, 2); // 增加 2 像素的字间距

7.设置字重 (weight)
QFont 提供多种预定义的字重(粗细),如 QFont::Thin、QFont::Light、QFont::Normal、QFont::Bold 等,通过 setWeight() 进行设置。
示例:

font.setWeight(QFont::Bold);

8.设置字体间距 (spacing)
设置字体的间距缩放因子,可以通过 setStretch() 方法调整字体宽度的百分比(默认 100%)。
示例:

font.setStretch(150); // 设置字体宽度为原来的 150%

9.字体大写转换 (capitalization)
设置字体的字母转换方式,通过 setCapitalization() 可指定不同的大写样式,如全部大写、小写字母等。

QFont::MixedCase:混合大小写(默认)
QFont::AllUppercase:全部大写
QFont::AllLowercase:全部小写
QFont::SmallCaps:小型大写字母

示例:

font.setCapitalization(QFont::AllUppercase);

10.设置字体样式策略 (StyleStrategy)
定义字体的渲染策略,比如抗锯齿、默认样式、强制替代字体等。
示例:

font.setStyleStrategy(QFont::PreferAntialias);

下面是一个简单的示例,展示了如何使用 QFont 设置字体,并用 QPainter 绘制文本:

QPainter painter(this);

    QFont font;
    font.setFamily("Times New Roman");
    font.setPointSize(14);
    font.setBold(true);
    font.setItalic(true);
    font.setUnderline(true);
    font.setLetterSpacing(QFont::AbsoluteSpacing, 2);
    font.setCapitalization(QFont::AllUppercase);

    painter.setFont(font);
    painter.drawText(10, 50, "Hello, QFont!");

    QWidget::paintEvent(event);

在这里插入图片描述

标签:Qt,填充,示例,2D,设置,绘制,QPainter
From: https://blog.csdn.net/TechNomad/article/details/143251802

相关文章

  • pyqt5实现nii文件叠加显示
            最近在做一个医学影像处理的项目,要求是使用pyqt5实现T1.nii文件和靶区文件的叠加显示。之前有web前端开发和一些python基础,pyqt5和医学影像文件(nii格式文件)处理都是第一次接触。趁着十一假期比较清闲,记录一下该功能实现的过程(pyqt5相关基础就不说了,B站很多新......
  • 树莓派CM4(五):搭建QT开发环境
    1.软件版本Ubuntu20.04QT5.12.122.参考链接https://zhuanlan.zhihu.com/p/138021025?utm_id=0https://zhuanlan.zhihu.com/p/137745265https://bugreports.qt.io/browse/QTBUG-62216https://www.tal.org/tutorials/building-qt-512-lts-raspberry-pi-raspberry-......
  • Ubuntu QTCreator 程序打包
    下载linuxdeployqt官网地址:https://github.com/probonopd/linuxdeployqt/releases安装更改名字mvlinuxdeployqt-6-x86_64.AppImagelinuxdeployqtViewCode修改权限chmod777linuxdeployqtViewCode全局访问sudomvlinuxdeployqt/usr/local/binViewCode测试linuxd......
  • vs+qt修改本地ico(已有一份ico)
    (此方法只修改文件夹里exe的ico,运行时的ico需要从ui文件中修改)1、有ICO文件2、右键项目,添加ico资源3、选择ico文件,此时项目列表中会出现ico文件4、清楚项目,重新生成项目5、右键rc文件,查看代码6、此时会出现两个ico7、关闭rc文件,找到resource.h文件,打开8、找到IDI_ICON......
  • 【QT】Qt窗口(上)
    个人主页~Qt窗口一、菜单栏二、工具栏三、状态栏四、浮动窗口Qt窗口是通过QMainWindow类来实现的,我们之前的学习是通过QWidget类实现的QMainWindow包含一个菜单栏MenuBar②,多个工具栏ToolBars③,多个浮动窗口DockWidgets,一个状态栏StatusBar⑤和一个中心部件......
  • qt标题,解决title的png图片scaled后显示有明显锯齿
    一、通用方法(使用Qlabel)//添加窗口图标iconLabel=newQLabel(this);QPixmapiconPixmap(":/ico.png");//替换成你的图标文件路径iconLabel->setPixmap(iconPixmap.scaled(125,35,Qt::KeepAspectRatio,Qt::SmoothTransformation));iconLayout->addWidget(iconLabel);......
  • Qt 实现启动动画
    受bilibili客户端启发,同款效果动画初始化voidMainWindow::initOverlayLabelAnimation(){//在centralwidget上创建一个覆盖的labeloverlayLabel=newQLabel(this);//加载logo图片QPixmappix=QPixmap(PNG_LINEX);floatscaled=0.3;ov......
  • Qt电子相册
    目录项目要求项目实现 ui设计代码dialog.hdialog.cpp源码项目要求基于作业3.0,增添以下功能:1.优化图片和代码逻辑2.增加自动翻页功能3.增加试试手气功能项目实现 ui设计 代码dialog.h#ifndefDIALOG_H#defineDIALOG_H#include<QDialog>#incl......
  • Qt作业3.0
    目录题目:ui界面设计:​编辑代码:dialog.hdialog.cppmain.cpp源码:题目:设计一个电子相册,点击上一张,切换到上一张图片,点击下一张,切换到下一张图片。要求:图片的展示可以循环,使用QList<QString>存储图片路径ui界面设计:代码:dialog.h//头文件dialog.h#ifn......
  • day10(Qt)OpenCV
    目录OpenCV1.OpenCV简介2.环境搭建3.人脸检测OpenCV1.OpenCV简介OpenCV(OpenSourceComputerVisionLibrary)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉功能。该库由英特尔公司发起,并在BSD许可证下发布,因此它是免费的,且开放源代码。OpenCV......