找回密码
 立即注册
首页 业界区 业界 Qt技巧笔记(十):QPainter 详解与实践指南 ...

Qt技巧笔记(十):QPainter 详解与实践指南

琉艺戕 2 小时前
Qt技巧笔记(十):QPainter 详解与实践指南

1. QPainter 概述

​        QPainter是Qt框架中用于二维图形绘制的核心类,其提供了一套完整、强大的API来在各种绘制设备上进行图形操作。无论是简单的线条绘制还是复杂的图形变换,广泛用于自定义控件、绘制背景、图形编辑器等场景。由QPainter、QPaintDevice 、QPaintEngine三类共同构成了Qt强大的二维绘图系统。

  • QPainter 用于执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice 显示图形(线、形状、渐变等),文本和图形。
  • QPaintDevice 不直接绘制物理显示画图,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到QWidget、QGLPixelBuffer、QImage 、QPixmap、QPicture等多种界面中间,必须使用QPaintDevice。
  • QPaintEngine 提供了一些接口,可用于QPainter在不同的设备上进行绘制。
​        绘图系统由 QPainter 完成具体的绘制操作,QPainter 类提供了大量高度优化的函数来完成 GUI 编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。此外,QPainter 也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter 也支持线性变换,例如平移、旋转、缩放。

2. QPainter 绘制图形的常用方法

QPainter 的常用方法按照功能分类进行总结,方便你快速查阅和使用。
类别API接口参数含义功能说明基本类型drawPoint(int x, int y)x: 点的X坐标;
y: 点的Y坐标绘制单个点void drawPoint(const QPoint &p)p: 包含X和Y坐标的点对象绘制单个点void drawLine(int x1, int y1, int x2, int y2)x1,y1: 起点坐标;
x2,y2: 终点坐标绘制直线void drawLine(const QPoint &p1, const QPoint &p2)p1: 起点;p2: 终点绘制直线void drawLine(const QLine &line)line: 包含起点和终点的直线对象绘制直线void drawRect(int x, int y, int w, int h)x,y: 左上角坐标;w: 宽度;h: 高度绘制矩形 void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)rect: 矩形区域;xRadius: X轴圆角半径;
yRadius: Y轴圆角半径;
mode: 半径单位模式(绝对尺寸或相对尺寸)绘制圆角矩形void drawEllipse(const QRectF &rect)center: 椭圆中心;rx: X轴半径;ry: Y轴半径绘制椭圆void drawEllipse(const QRectF &rect)rect: 椭圆的外接矩形绘制椭圆void drawEllipse(const QRect &rect)rect: 椭圆的外接矩形绘制椭圆void drawEllipse(int x, int y, int w, int h)x,y,w,h: 外接矩形的参数绘制椭圆void drawArc(const QRectF &rect, int startAngle, int spanAngle)ct: 弧所在椭圆的外接矩形;
startAngle: 起始角度(1/16度);
spanAngle: 跨越角度(1/16度)绘制弧线void drawPie(const QRectF &rect, int startAngle, int spanAngle)参数同上绘制扇形(包含圆心)void drawChord(const QRectF &rect, int startAngle, int spanAngle)rect: 弧所在椭圆的外接矩形;
startAngle: 起始角度(1/16度);
spanAngle: 跨越角度(1/16度)绘制弦(弧两端连线封闭)void drawChord(int x, int y, int w, int h, int startAngle, int spanAngle)同上绘制弦void drawPolygon(const QPolygonF &polygon, Qt::FillRule fillRule = Qt::OddEvenFill)polygon: 多边形顶点列表;
fillRule: 填充规则(
奇偶填充或弯曲填充)绘制多边形void drawPolygon(const QPolygon &polygon, Qt::FillRule fillRule = Qt::OddEvenFill)同上绘制多边形void drawConvexPolygon(const QPolygonF &polygon)polygon: 凸多边形顶点列表绘制凸多边形(效率更高)void drawConvexPolygon(const QPolygon &polygon)同上绘制凸多边形文本void drawText(const QPointF &pos, const QString &text)pos: 文本基线左端点;
text: 要绘制的文本绘制文本void drawText(int x, int y, const QString &text)x,y: 文本基线左端点坐标;
text: 文本绘制文本void drawText(const QRectF &rect, int flags, const QString &text, QRectF *boundingRect = nullptr)rect: 文本绘制区域;
flags: 对齐标志(如Qt::AlignCenter);
text: 文本;
boundingRect: 返回实际文本边界在矩形内绘制文本void drawText(const QRect &rect, int flags, const QString &text, QRect *boundingRect = nullptr)同上,使用整数矩形在矩形内绘制文本void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *boundingRect = nullptr)x,y,w,h: 矩形参数;
其余同上在矩形内绘制文本QRectF boundingRect(const QRectF &rect, int flags, const QString &text)参数同上,无boundingRect输出参数;
返回计算出的文本边界矩形计算文本边界QRect boundingRect(const QRect &rect, int flags, const QString &text)同上计算文本边界图像与像素图void drawImage(const QPointF &point, const QImage &image)point: 图像左上角放置位置;
image: 要绘制的图像绘制QImage的指定区域到目标区域void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags = Qt::AutoColor)target: 目标区域(可能缩放);       image: 源图像;
source: 源图像中要绘制的子区域;flags: 颜色转换选项绘制QPixmapvoid drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)target: 目标区域;pixmap: 源像素图;source: 源图像中要绘制的子区域绘制QPixmap指定区域到目标区域void drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &offset = QPointF())rect: 要平铺填充的目标区域;
pixmap: 平铺用的像素图;
offset: 平铺起始偏移平铺绘制像素图复杂路径void drawPath(const QPainterPath &path)path: 包含直线、曲线等子路径的路径对象绘制复杂路径填充与擦除void fillRect(const QRectF &rect, const QBrush &brush)rect: 要填充的矩形;
brush: 画刷(定义颜色、样式、渐变等)填充矩形void fillRect(int x, int y, int w, int h, const QColor &color)x,y,w,h: 矩形参数;color: 填充颜色填充矩形void fillRect(const QRect &rect, Qt::GlobalColor color)rect: 矩形;color: 全局颜色枚举(如Qt::red)填充矩形void eraseRect(const QRectF &rect)rect: 要擦除的矩形区域擦除矩形(用背景色填充)void eraseRect(int x, int y, int w, int h)x,y,w,h: 矩形参数擦除矩形状态与变换void save()无参数保存当前画家状态(画笔、画刷、变换等)void restore()无参数恢复上次保存的画家状态void translate(qreal dx, qreal dy)dx: X轴偏移量;dy: Y轴偏移量平移坐标系void translate(const QPointF &offset)offset: 包含dx和dy的偏移向量平移坐标系void rotate(qreal angle)angle: 旋转角度(度,顺时针为正)旋转坐标系void scale(qreal sx, qreal sy)sx: X轴缩放因子;sy: Y轴缩放因子缩放坐标系void shear(qreal sh, qreal sv)sh: 水平剪切因子;sv: 垂直剪切因子剪切坐标系void setRenderHint(RenderHint hint, bool on = true)hint: 渲染提示枚举(如Antialiasing);on: 启用或禁用设置渲染选项注意:在默认情况下,QPainter 使用的坐标系非常简单直接:

  • 原点 (Origin):位于绘图设备(如QWidget窗口、QPixmap等)的左上角 (0, 0)。
  • X轴方向:水平向右,数值递增。
  • Y轴方向:垂直向下,数值递增。
  • 单位 (Unit):在基于像素的设备(如屏幕)上,1个单位代表 1个像素;在打印机上,1个单位代表1个点(1/72 英寸)。
这种设计符合屏幕显示的常规认知。
3. QPainter 的基本使用详解

3.1 初始化与资源管理

QPainter 必须在绘制设备(QPaintDevice 的子类,如 QWidget、QPixmap、QImage 等)上工作。初始化即建立 QPainter 与设备的关联。
  1. // 在QPixmap上绘制
  2. QPixmap pixmap(200, 200);
  3. pixmap.fill(Qt::white);
  4. {
  5.     QPainter painter(&pixmap); // 自动开始绘制
  6.     // 绘制操作
  7. } // 自动结束绘制,资源释放
  8. // 在QWidget的paintEvent中
  9. void MyWidget::paintEvent(QPaintEvent *event)
  10. {
  11.     QPainter painter(this); // this指向当前widget
  12.     // 绘制操作
  13. }
复制代码
3.2 通过Qpen 画笔设置样式的例子

​        在 Qt 中,QPen 定义了绘制线条和轮廓线的样式。通过 QPen 可以设置线的颜色、宽度、线型(实线、虚线等)、笔帽样式(端点形状)以及连接样式(折线连接处的形状)。下面通过完整的示例展示如何使用 QPen 设置各种样式。
  1. QPen pen;
  2. pen.setColor(QColor(255, 0, 0));    // 红色
  3. pen.setWidth(3);                    // 3像素宽度
  4. pen.setStyle(Qt::DashLine);         // 虚线样式
  5. pen.setCapStyle(Qt::RoundCap);      // 线端圆角
  6. painter.setPen(pen);
复制代码
完整案例:绘制不同笔样式的线段
  1. #include <QPainter>
  2. #include <QWidget>
  3. #include <QApplication>
  4. class PenDemoWidget : public QWidget
  5. {
  6. protected:
  7.     void paintEvent(QPaintEvent *event) override
  8.     {
  9.         QPainter painter(this);
  10.         painter.setRenderHint(QPainter::Antialiasing);  // 抗锯齿让线条平滑
  11.         // 设置坐标和间隔
  12.         int y = 30;
  13.         int step = 30;
  14.         // 1. 默认实线
  15.         QPen pen1;
  16.         painter.setPen(pen1);
  17.         painter.drawLine(20, y, 300, y);
  18.         painter.drawText(310, y+5, "SolidLine (default)");
  19.         y += step;
  20.         // 2. 红色虚线,宽度2
  21.         QPen pen2(Qt::red, 2, Qt::DashLine);
  22.         painter.setPen(pen2);
  23.         painter.drawLine(20, y, 300, y);
  24.         painter.drawText(310, y+5, "DashLine");
  25.         y += step;
  26.         // 3. 蓝色点线,宽度3,圆帽
  27.         QPen pen3;
  28.         pen3.setColor(Qt::blue);
  29.         pen3.setWidth(3);
  30.         pen3.setStyle(Qt::DotLine);
  31.         pen3.setCapStyle(Qt::RoundCap);
  32.         painter.setPen(pen3);
  33.         painter.drawLine(20, y, 300, y);
  34.         painter.drawText(310, y+5, "DotLine + RoundCap");
  35.         y += step;
  36.         // 4. 绿色点划线,宽度2,方形帽
  37.         QPen pen4(QBrush(Qt::green), 2, Qt::DashDotLine);
  38.         pen4.setCapStyle(Qt::SquareCap);
  39.         painter.setPen(pen4);
  40.         painter.drawLine(20, y, 300, y);
  41.         painter.drawText(310, y+5, "DashDotLine + SquareCap");
  42.         y += step;
  43.         // 5. 自定义虚线模式
  44.         QPen pen5;
  45.         pen5.setColor(Qt::magenta);
  46.         pen5.setWidth(2);
  47.         QVector<qreal> dashes;
  48.         dashes << 5 << 2 << 10 << 2;  // 画5空2画10空2
  49.         pen5.setDashPattern(dashes);
  50.         pen5.setStyle(Qt::CustomDashLine);
  51.         painter.setPen(pen5);
  52.         painter.drawLine(20, y, 300, y);
  53.         painter.drawText(310, y+5, "CustomDash (5,2,10,2)");
  54.         y += step;
  55.         // 6. 连接样式演示:绘制折线
  56.         y += 30;
  57.         painter.setPen(QPen(Qt::darkYellow, 8, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
  58.         drawPoly(&painter, y, "MiterJoin"); y += 80;
  59.         painter.setPen(QPen(Qt::darkYellow, 8, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
  60.         drawPoly(&painter, y, "BevelJoin"); y += 80;
  61.         painter.setPen(QPen(Qt::darkYellow, 8, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin));
  62.         drawPoly(&painter, y, "RoundJoin");
  63.     }
  64.     void drawPoly(QPainter *painter, int yOffset, const QString &label)
  65.     {
  66.         QPolygon poly;
  67.         poly << QPoint(50, yOffset) << QPoint(150, yOffset+30) << QPoint(250, yOffset-20);
  68.         painter->drawPolyline(poly);
  69.         painter->drawText(260, yOffset+5, label);
  70.     }
  71. };
  72. int main(int argc, char *argv[])
  73. {
  74.     QApplication app(argc, argv);
  75.     PenDemoWidget w;
  76.     w.resize(500, 500);
  77.     w.show();
  78.     return app.exec();
  79. }
复制代码
6. QPainter 总结

​        QPainter作为Qt图形系统的核心,提供了强大而灵活的二维图形绘制能力。通过掌握其基本用法和高级特性,开发者可以实现从简单的UI元素到复杂的数据可视化等各种图形需求。关键在于理解其状态机模型和坐标系变换机制,结合合理的优化策略,就能创造出既美观又高效的图形应用程序。无论是桌面应用、嵌入式界面还是数据可视化项目,QPainter都是Qt开发者不可或缺的强大工具。希望本文能帮助读者深入理解并有效运用这一重要的图形绘制框架。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册