
04_Qt教案 绘图篇
本文最后更新于 2025-02-20,学习久了要注意休息哟
第一章 绘图基础
1.1 绘图简介
1.1.1 绘图在 Qt 中的作用
- 自定义控件:Qt 提供了强大的绘图功能,允许开发者创建具有定制化外观和行为的控件。这对于绘制复杂的图形和交互式组件(如自定义按钮、滑块等)非常有用。
- 图形编辑器:Qt 的绘图框架使得开发图形编辑器、绘图程序变得简单。比如:绘制线条、矩形、圆形、自由图形等,以及处理鼠标和键盘输入事件。
- 游戏开发:对于游戏开发中的图形渲染,Qt 提供了强大的绘制支持,允许开发者进行快速的界面绘制和动画效果实现。
1.1.2 Qt 的绘图框架
- QPainter:是 Qt 中绘制图形的核心类,提供了大量的绘图方法来绘制基本形状、文本和图像。
- QWidget 的关系:
QWidget
是所有 Qt 控件的基类,所有控件的绘制操作都是通过重写paintEvent()
方法来实现的,通常在paintEvent()
中会创建一个QPainter
对象来完成绘图任务。 - 绘图设备:
QPainter
可以在不同的设备上绘制图形,包括窗口、图像、打印机等。不同的绘图设备有不同的实现方式,但它们都支持 QPainter。
1.2 QPainter 基础
1.2.1 QPainter 类的简介
- 作用:
QPainter
类提供了在不同绘图设备上绘制图形的方法。它是 Qt 的绘图核心,允许开发者绘制点、线、矩形、圆形、文本等。 - 常用方法:
begin()
: 开始绘图,指定绘图设备。end()
: 结束绘图操作,释放资源。setPen()
: 设置画笔,用于绘制线条和轮廓。setBrush()
: 设置画刷,用于填充图形。drawLine()
: 绘制直线。drawRect()
: 绘制矩形。drawEllipse()
: 绘制椭圆或圆形。drawText()
: 绘制文本。setRenderHint()
: 设置渲染提示(如抗锯齿)。
1.2.2 创建 QPainter 对象的方式
创建和初始化 QPainter:
在 paintEvent()
中使用:大多数情况下,我们会在重写的 paintEvent()
方法中创建 QPainter
对象。paintEvent()
会自动接收到一个 QPaintEvent
事件,作为绘图事件的触发函数。
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this); // 创建 QPainter 对象
painter.setRenderHint(QPainter::Antialiasing); // 启用抗锯齿
painter.drawRect(10, 10, 100, 100); // 绘制矩形
}
绘制其他设备:如在 QImage
或 QPixmap
上绘图时,需要在构造函数中指定相应的设备。
QImage image(500, 500, QImage::Format_ARGB32);
QPainter painter(&image);
painter.setPen(Qt::red);
painter.drawLine(0, 0, 500, 500);
1.2.3 QPainter 常用的绘制操作
绘制线条
drawLine()
方法绘制直线。
painter.drawLine(10, 10, 100, 100); // 绘制从 (10, 10) 到 (100, 100) 的线段
绘制矩形
drawRect()
方法绘制矩形。
painter.drawRect(10, 10, 100, 50); // 绘制一个宽 100,高 50 的矩形
绘制圆形/椭圆
drawEllipse()
方法绘制圆形或椭圆。
painter.drawEllipse(10, 10, 100, 100); // 绘制一个圆形
绘制路径
QPainterPath
类绘制复杂的图形(如贝塞尔曲线)。
QPainterPath path; path.moveTo(50, 50); path.lineTo(100, 100); painter.drawPath(path);
绘制文本
drawText()
方法绘制文本。
painter.drawText(10, 10, "Hello, Qt!"); // 绘制文本
1.2.4 使用 QPainter::begin() 和 QPainter::end()
begin()
:在绘制之前调用
begin()
,用于初始化绘图设备。
QPainter painter; painter.begin(this); // 在控件上开始绘制
end()
:绘制完成后调用
end()
,用于清理资源。
painter.end(); // 结束绘制
1.3 设备坐标系
1.3.1 坐标系的基本概念
- 原点:坐标系的起始点,通常为
(0, 0)
。 - 方向:在二维坐标系中,x轴从左到右为正方向,y轴从上到下为正方向。
- 单位:在屏幕显示设备中,单位通常是像素,代表显示器的分辨率。
1.3.2 QPainter 和设备坐标系的关系
- QWidget 坐标系:默认情况下,
QPainter
使用控件的坐标系(即QWidget
的坐标系)进行绘制。绘制的坐标原点位于控件的左上角。 - QPixmap 和 QImage 坐标系:对于图像设备,
QPainter
会使用图像的坐标系来绘制,原点通常是图像的左上角。
1.3.3 使用 QPainter::setTransform() 操作坐标变换
坐标变换
:可以通过
QPainter::setTransform()
来对绘图坐标进行缩放、旋转、平移等操作。
- 平移:移动坐标系的位置。
painter.translate(50, 50); // 将坐标系平移到 (50, 50)
- 旋转:绕原点旋转坐标系。
painter.rotate(45); // 将坐标系顺时针旋转 45 度
- 缩放:对坐标系进行缩放。
painter.scale(2.0, 2.0); // 将坐标系缩放 2 倍
QTransform:
QPainter::setTransform()
接受一个QTransform
对象,QTransform
用于管理坐标变换。
第二章 绘制前的准备
在进行绘图之前,首先需要创建一个 QPainter
对象,并通过 begin()
和 end()
方法来控制绘图的开始和结束。我们通常会在控件的 paintEvent
方法中进行绘制。
2.1 画笔
2.1.1 画笔设置
QPen::QPen
QPen::QPen(const QColor &color)
。。。
2.1.2 画笔宽度
// 获取画笔的宽度(整数类型)
int width() const;
// 设置画笔的宽度
void setWidth(int width);
// 获取画笔的宽度(浮点类型)
qreal widthF() const;
// 设置画笔的宽度(浮点类型)
void setWidthF(qreal width);
2.1.3 画笔颜色
// 获取画笔的颜色
QColor color() const;
// 设置画笔的颜色
void setColor(const QColor &color);
2.1.4 画笔样式
// 获取画笔的样式
Qt::PenStyle style() const;
// 设置画笔的样式
void setStyle(Qt::PenStyle style);
2.1.4 连接
// 获取和设置画笔的 Join 样式
Qt::PenJoinStyle joinStyle() const;
void setJoinStyle(Qt::PenJoinStyle style)
2.1.5 末端
// 获取和设置画笔的 Cap 样式
Qt::PenCapStyle capStyle() const;
void setCapStyle(Qt::PenCapStyle style)
2.1.6 示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 创建一个红色画笔,宽度为 3,实线
QPen pen(Qt::red, 3, Qt::SolidLine);
painter.setPen(pen); // 设置画笔
// 绘制一条直线
painter.drawLine(10, 10, 200, 200);
// 修改画笔属性为蓝色,虚线
pen.setColor(Qt::blue);
pen.setStyle(Qt::DashLine);
painter.setPen(pen); // 更新画笔
// 绘制一条虚线
painter.drawLine(10, 200, 200, 10);
}
2.2 画刷
2.2.1 画刷颜色
// 获取和设置画刷的颜色
const QColor &color() const
void setColor(const QColor &color)
2.2.2 样式
// 获取和设置画刷的样式
Qt::BrushStyle style() const
void setStyle(Qt::BrushStyle style)
第三章 基本图形
3.1 点与线
在 Qt 中,点和线是最基本的图形元素,通常用于构建更复杂的图形。QPainter
提供了多种方法来绘制点、线和与之相关的图形。
3.1.1 点绘制
QPainter
提供了 drawPoint()
方法用于绘制单个点。
API
// 绘制一个点
// 绘制一个指定位置的点。
void QPainter::drawPoint(int x, int y);
// 绘制一个指定位置的点,使用 QPoint 对象表示坐标。
void QPainter::drawPoint(const QPoint &point);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为蓝色,宽度为3
QPen pen(Qt::blue);
pen.setWidth(3);
painter.setPen(pen);
// 绘制一条从(50, 50)到(200, 200)的线
painter.drawLine(50, 50, 200, 200);
}
3.1.2 线绘制
API
// 绘制一条线
// 绘制一条从 (x1, y1) 到 (x2, y2) 的直线。
void QPainter::drawLine(int x1, int y1, int x2, int y2);
// 绘制通过 QLine 对象指定的线。
void QPainter::drawLine(const QLine &line);
// 绘制连接 p1 和 p2 的直线。
void QPainter::drawLine(const QPoint &p1, const QPoint &p2);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为蓝色,宽度为3
QPen pen(Qt::blue);
pen.setWidth(3);
painter.setPen(pen);
// 绘制一条从(50, 50)到(200, 200)的线
painter.drawLine(50, 50, 200, 200);
}
3.1.3 示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 绘制多个点
QPen pen1(Qt::green);
pen1.setWidth(4);
painter.setPen(pen1);
painter.drawPoint(50, 50);
painter.drawPoint(150, 150);
painter.drawPoint(250, 250);
// 绘制一条线
QPen pen2(Qt::blue);
pen2.setWidth(2);
painter.setPen(pen2);
painter.drawLine(50, 50, 250, 250); // 绿色点到蓝色线的连接
// 绘制另一条线
QPen pen3(Qt::red);
pen3.setWidth(5);
pen3.setStyle(Qt::DashLine); // 设置虚线
painter.setPen(pen3);
painter.drawLine(150, 150, 50, 250); // 红色虚线
}
3.2 多边形与多段线
在 Qt 中,绘制多边形和多段线是常见的图形操作。QPainter
提供了相关的 API 来绘制这些复杂的图形。多边形是由一系列连续的直线段围成的闭合区域,而多段线是由多个直线段组成,但不一定是闭合的。
3.2.1 多边形绘制
QPainter
提供了 drawPolygon()
方法来绘制多边形。QPolygon
是一个由多个点组成的容器,通常用来表示多边形的顶点。
API
// 绘制多边形
void QPainter::drawPolygon(const QPoint *points, int pointCount);
void QPainter::drawPolygon(const QPolygon &polygon);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为蓝色
QPen pen(Qt::blue);
pen.setWidth(3);
painter.setPen(pen);
// 定义一个多边形
QPoint points[4] = { QPoint(50, 50), QPoint(150, 50), QPoint(150, 150), QPoint(50, 150) };
painter.drawPolygon(points, 4); // 绘制一个四边形
}
3.2.2 多段线绘制
多段线绘制使用 QPainter
的 drawPolyline()
方法。多段线由多个连续的线段组成,但它不要求形成一个封闭的区域。
API
// 绘制多段线
// 传入一个点数组和点的数量来绘制多边形。
void QPainter::drawPolyline(const QPoint *points, int pointCount);
// 传入一个 QPolygon 对象来绘制多边形。
void QPainter::drawPolyline(const QPolygon &polyline);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为红色
QPen pen(Qt::red);
pen.setWidth(2);
painter.setPen(pen);
// 定义多段线的点
QPoint points[5] = { QPoint(50, 50), QPoint(100, 100), QPoint(150, 50), QPoint(200, 100), QPoint(250, 50) };
painter.drawPolyline(points, 5); // 绘制多段线
}
3.2.3 示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为红色
QPen pen(Qt::red);
pen.setWidth(2);
painter.setPen(pen);
// 定义多段线的点
QPoint points[5] = { QPoint(50, 50), QPoint(100, 100), QPoint(150, 50), QPoint(200, 100), QPoint(250, 50) };
painter.drawPolyline(points , 5); // 绘制多段线
}
3.3 矩形与圆角矩形
3.3.1 矩形
API
// 绘制矩形
// 指定矩形的左上角位置(x, y)和矩形的宽度和高度
void QPainter::drawRect(int x, int y, int width, int height);
// 使用 QRect 对象来定义矩形的区域
void QPainter::drawRect(const QRect &rect);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔颜色
QPen pen(Qt::blue);
pen.setWidth(3);
painter.setPen(pen);
// 绘制矩形
painter.drawRect(50, 50, 200, 100); // 使用左上角坐标和宽高绘制矩形
// 或者使用 QRect 绘制矩形
QRect rect(50, 200, 200, 100);
painter.drawRect(rect); // 使用 QRect 绘制矩形
}
3.3.2 圆角矩形
API
// 绘制圆角矩形
// 指定圆角矩形的矩形区域、宽度、高度以及水平和垂直方向的圆角半径
void QPainter::drawRoundedRect(int x, int y, int width, int height, qreal xRadius, qreal yRadius);
// 使用 QRect 对象来指定矩形的区域,同时指定圆角半径
void QPainter::drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔为红色
QPen pen(Qt::red);
pen.setWidth(2);
painter.setPen(pen);
// 绘制圆角矩形
painter.drawRoundedRect(50, 50, 200, 100, 20, 20); // 使用左上角坐标和宽高以及圆角半径绘制圆角矩形
// 或者使用 QRect 绘制圆角矩形
QRect rect(50, 200, 200, 100);
painter.drawRoundedRect(rect, 20, 20); // 使用 QRect 绘制圆角矩形
}
3.4 椭圆与圆形
3.4.1 椭圆
API
// 绘制椭圆
// 根据指定的矩形位置和宽高来绘制椭圆
void QPainter::drawEllipse(int x, int y, int width, int height);
// 使用 QRect 对象来指定椭圆的区域。
void QPainter::drawEllipse(const QRect &rect);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔颜色
QPen pen(Qt::green);
pen.setWidth(2);
painter.setPen(pen);
// 绘制椭圆
painter.drawEllipse(50, 50, 200, 100); // 绘制一个宽200、高100的椭圆
// 使用 QRect 绘制椭圆
QRect rect(50, 200, 200, 100);
painter.drawEllipse(rect); // 使用 QRect 绘制椭圆
}
3.4.2 圆形
API
// 绘制圆形
void QPainter::drawEllipse(int x, int y, int diameter, int diameter);
void QPainter::drawEllipse(const QRect &rect);
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔颜色
QPen pen(Qt::blue);
pen.setWidth(3);
painter.setPen(pen);
// 绘制圆形
painter.drawEllipse(50, 50, 100, 100); // 绘制一个半径为50的圆形
// 使用 QRect 绘制圆形
QRect rect(50, 200, 100, 100); // 使用一个正方形的 QRect 绘制圆形
painter.drawEllipse(rect); // 使用 QRect 绘制圆形
}
3.6 路径与圆弧
3.6.1 路径
API
// 将绘制位置移动到指定坐标 (x, y),并且不画线。
QPainterPath::moveTo(qreal x, qreal y)
// 从当前位置画一条直线到 (x, y)。
QPainterPath::lineTo(qreal x, qreal y)
// 绘制圆弧,从 startAngle 开始,跨越 spanAngle 度数,圆弧的外接矩形由 rect 定义。
QPainterPath::arcTo(const QRectF &rect, qreal startAngle, qreal spanAngle)
// 绘制三次贝塞尔曲线。
QPainterPath::cubicTo(qreal x1, qreal y1, q2, q2, q3, q3)
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔颜色
QPen pen(Qt::green);
pen.setWidth(2);
painter.setPen(pen);
// 创建路径
QPainterPath path;
// 使用 moveTo 移动到起点
path.moveTo(50, 50);
// 使用 lineTo 绘制直线
path.lineTo(150, 50); // 直线到 (150, 50)
// 使用 arcTo 绘制圆弧
path.arcTo(50, 50, 100, 100, 0, 180); // 从 (50, 50) 绘制半圆
// 使用 cubicTo 绘制三次贝塞尔曲线
path.cubicTo(75, 150, 125, 150, 150, 100); // 三次贝塞尔曲线
// 绘制路径
painter.drawPath(path);
}
3.6.2 圆弧
API
// 绘制圆弧,从 startAngle 开始,跨越 spanAngle 度数,圆弧的外接矩形由 rect 定义。
QPainterPath::arcTo(const QRectF &rect, qreal startAngle, qreal spanAngle)
@ rect:圆弧的外接矩形,决定圆弧的大小和位置。
@ startAngle:圆弧的起始角度,以 1/16 度为单位(360 度 = 5760)。
@ spanAngle:圆弧的跨越角度,以 1/16 度为单位,表示圆弧的跨度。
示例程序
void MyWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// 设置画笔颜色
QPen pen(Qt::blue);
pen.setWidth(2);
painter.setPen(pen);
// 创建路径
QPainterPath path;
// 绘制圆弧,外接矩形 (50, 50, 100, 100),从 0 度开始,跨越 90 度
path.arcTo(50, 50, 100, 100, 0, 90); // 绘制 90 度的圆弧
// 绘制路径
painter.drawPath(path);
}
3.5 圆饼与弦图
3.5.1 圆饼
3.5.2 弦图
第四章 图像与文本
4.1 文本
4.2 图像
4.3 平移、旋转、缩放
- 感谢你赐予我前进的力量