
🔥个人主页:Cx330🌸
❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》
《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔
《Git深度解析》:版本管理实战全解 《Qt 极境架构》MySQL 核心技术与实战
🌟心向往之行必能
🎥Cx330🌸的简介:

目录
[一、 Qt 绘图四大核心角色](#一、 Qt 绘图四大核心角色)
[1.2 绘图的核心原则](#1.2 绘图的核心原则)
[二. 基础绘图:绘制形状与文本](#二. 基础绘图:绘制形状与文本)
[2.1 绘制基础形状](#2.1 绘制基础形状)
[2.1.1 绘制线段](#2.1.1 绘制线段)
[2.1.2 绘制矩形](#2.1.2 绘制矩形)
[2.1.3 绘制圆形 / 椭圆](#2.1.3 绘制圆形 / 椭圆)
[2.1.3 绘制圆形 / 椭圆](#2.1.3 绘制圆形 / 椭圆)
[2.2 绘制文本](#2.2 绘制文本)
[2.3 自定义画笔与画刷](#2.3 自定义画笔与画刷)
[2.3.1 自定义画笔](#2.3.1 自定义画笔)
[2.3.2 自定义画刷](#2.3.2 自定义画刷)
[三. 图片处理:绘制、缩放与旋转](#三. 图片处理:绘制、缩放与旋转)
[3.1 绘制图片(QPixmap)](#3.1 绘制图片(QPixmap))
[3.2 图片平移与旋转](#3.2 图片平移与旋转)
前言:
在 Qt 开发中,我们经常使用各种各样的控件(如 QPushButton、QLineEdit、QLabel等)。但你是否思考过,这些控件究竟是如何呈现到屏幕上的?
答案非常简单:本质上它们都是"画"出来的。Qt 已经提前帮我们绘制好了各种通用控件,拿来即用。但在实际项目中,当预设控件无法满足特殊需求时,我们就需要利用 Qt 提供的绘图 API 手动 DIY 自定义控件与视觉效果。
本文将根据 Qt 绘图的核心知识体系,由浅入深解析 Qt 的绘图机制、核心组件、绘制事件机制以及图像处理类。
一、 Qt 绘图四大核心角色
Qt 的绘图系统采用了一套现实生活中"画画"的拟人化设计概念:
|------------------|--------------|-----------------------------------------------------------|
| 类名 | 比喻 | 作用与功能描述 |
| QPainter | 绘图者(画师) | 提供具体的绘图方法(画线、画矩形、画文字等),负责执行绘画动作。 |
| QPaintDevice | 画板(绘图设备) | 绘图的目标载体。QWidget是 QPaintDevice的子类,因此所有窗口控件都可以作为画板。 |
| QPen | 画笔 | 用于绘制图形的轮廓线,控制线条的颜色、粗细、线型(实线、虚线等)。 |
| QBrush | 画刷 | 用于填充封闭图形的内部区域,控制填充的颜色、渐变色或纹理图案。 |

1.2 绘图的核心原则
- 绘图时机 :绘图操作必须在paintEvent事件中执行,该事件会在控件创建、大小改变、被遮挡恢复等场景下自动触发,也可通过**repaint()或update()**主动触发。
- 设备无关性:QPainter 可在任意 QPaintDevice 子类上绘图,无论是窗口(QWidget)、图片(QPixmap)还是像素缓冲区(QImage),接口完全一致。
- 状态管理 :QPainter 支持save()(保存当前状态)和restore()(恢复之前状态),方便复杂绘图中的状态切换。


二. 基础绘图:绘制形状与文本
Qt 绘图 API 支持绘制线段、矩形、圆形、文本等基础元素,掌握这些是实现复杂效果的前提。
2.1 绘制基础形状
2.1.1 绘制线段
通过drawLine方法绘制线段,支持两种参数形式:QPoint坐标对或直接传入 x、y 坐标:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this); // 以当前窗口为画板
// 方式1:使用QPoint指定起点和终点
painter.drawLine(QPoint(20, 20), QPoint(200, 20));
// 方式2:直接传入x1,y1,x2,y2
painter.drawLine(20, 100, 200, 100);
}
2.1.2 绘制矩形
drawRect方法接收矩形左上角坐标和宽高:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 绘制左上角(20,20)、宽100、高50的矩形
painter.drawRect(20, 20, 100, 50);
}
2.1.3 绘制圆形 / 椭圆
drawEllipse方法通过中心点坐标和 x、y 轴半径绘制,当 x、y 半径相等时即为圆形:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 绘制中心点(100,100)、半径50的圆形
painter.drawEllipse(QPoint(100, 100), 50, 50);
// 绘制椭圆(x半径30,y半径50)
painter.drawEllipse(QPoint(250, 100), 30, 50);
}
2.1.3 绘制圆形 / 椭圆
drawEllipse方法通过中心点坐标和 x、y 轴半径绘制,当 x、y 半径相等时即为圆形:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 绘制中心点(100,100)、半径50的圆形
painter.drawEllipse(QPoint(100, 100), 50, 50);
// 绘制椭圆(x半径30,y半径50)
painter.drawEllipse(QPoint(250, 100), 30, 50);
}
2.2 绘制文本
通过drawText绘制文本,支持设置字体 、颜色等样式:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 设置字体(华文行楷,24号)
QFont font("华文行楷", 24);
painter.setFont(font);
// 设置文本颜色为红色
painter.setPen(Qt::red);
// 在矩形区域(100,200,600,150)内绘制文本(自动换行)
painter.drawText(QRect(100, 200, 600, 150), "天行健,君子以自强不息");
}
2.3 自定义画笔与画刷
默认的画笔和画刷样式单一,通过 QPen 和 QBrush 可实现个性化效果。
2.3.1 自定义画笔
QPen支持设置颜色、宽度、线条样式:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
QPen pen(QColor(255, 0, 0)); // 红色画笔
pen.setWidth(3); // 线宽3像素
pen.setStyle(Qt::DashLine); // 虚线样式(可选SolidLine、DotLine等)
painter.setPen(pen); // 画家使用该画笔
painter.drawEllipse(QPoint(100, 100), 50, 50);
}

2.3.2 自定义画刷
QBrush用于填充封闭图形,支持纯色、渐变、纹理 等填充模式:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 1. 纯色填充(青色)
QBrush brush(Qt::cyan);
// 2. 渐变填充(垂直渐变:白色→黑色)
// QBrush brush(QLinearGradient(0,0,0,200));
// brush.gradient()->setColorAt(0, Qt::white);
// brush.gradient()->setColorAt(1, Qt::black);
// 3. 纹理填充(使用图片)
// QBrush brush(QPixmap(":/texture.png"));
brush.setStyle(Qt::Dense1Pattern); // 填充样式(可选不同密度的图案)
painter.setBrush(brush);
painter.drawEllipse(QPoint(100, 100), 50, 50);
}

-
补充例子:大家可以看看
// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{
Q_OBJECTpublic:
Widget(QWidget parent = nullptr);
~Widget();
void paintEvent(QPaintEvent enent);private:
Ui::Widget *ui;
};
#endif // WIDGET_H// widget.cpp
#include "widget.h"
#include "ui_widget.h"#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}Widget::~Widget()
{
delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{
(void)event;
// 绘图工作就会放在这里执行
QPainter painter(this);// 画一个线段// painter.drawLine(20,20,200,20);
// painter.drawLine(QPoint(20,20),QPoint(200,20));
// painter.drawLine(20,20,300,200);// 画一个矩形// painter.drawRect(100,100,300,200);
// // 画一个圆形
// painter.drawEllipse(200,200,200,50); // 后面两个参数其实是外接矩形的宽度高度// 绘制文本// painter.drawText(10,100,"hello");
// QFont font("微软雅黑", 24);
// painter.setFont(font);QPen pen; // 设置成红色的线条 pen.setColor(QColor(255,0,0)); // 设置线条的粗细 pen.setWidth(5); // 设置线条的风格 pen.setStyle(Qt::DashLine); // 让 painter 对象应用 pen 对象 painter.setPen(pen); QBrush brush; brush.setColor(QColor(0,255,0)); // brush.setStyle(Qt::SolidPattern); 填充风格 brush.setStyle(Qt::CrossPattern); painter.setBrush(brush); painter.drawEllipse(200,200,200,50);}

三. 图片处理:绘制、缩放与旋转
Qt 提供 QPixmap、QImage、QPicture 三种图片相关绘图设备,分别适用于不同场景。
3.1 绘制图片(QPixmap)
QPixmap 专为屏幕显示优化,加载图片后通过drawPixmap绘制:
// 1. 先添加资源文件(res.qrc),导入图片到picture文件夹
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 绘制原图(左上角坐标(0,0))
painter.drawPixmap(0, 0, QPixmap(":/picture/4.jpg"));
// 缩放绘制(左上角(300,400),宽50,高60)
painter.drawPixmap(300, 400, 50, 60, QPixmap(":/picture/4.jpg"));
}
3.2 图片平移与旋转
通过translate(坐标平移)和rotate(旋转)实现图片变换,注意旋转默认以原点为中心:
void Widget::paintEvent(QPaintEvent *) {
QPainter painter(this);
QPixmap pix(":/picture/4.jpg");
// 1. 平移图片(原点偏移(100,100))
painter.translate(100, 100);
painter.drawPixmap(0, 0, pix);
// 2. 旋转图片(以图片中心为旋转点)
painter.save(); // 保存当前状态
painter.translate(300 + pix.width()/2, 100 + pix.height()/2); // 平移到图片中心
painter.rotate(90); // 顺时针旋转90度
painter.translate(-(300 + pix.width()/2), -(100 + pix.height()/2)); // 还原原点
painter.drawPixmap(300, 100, pix);
painter.restore(); // 恢复状态
}

-
补充示例:(.h这里就不再展示了,跟之前的补充示例一样)
#include "widget.h"
#include "ui_widget.h"
#includeWidget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}Widget::~Widget()
{
delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{
(void)event;
QPainter painter(this);QPixmap pixmap(":/ins.png"); // 基础绘制// painter.drawPixmap(0,0,pixmap);
// painter.drawPixmap(100,100,pixmap);// 图片缩放// painter.drawPixmap(100,100,400,300,pixmap);
// 图片的旋转, 本质上是把 Qpainter 对象进行了需旋转, 绘制出来的内容也就旋转了 painter.rotate(180); // 默认绕原点(0,0)旋转,所以会到屏幕外去 painter.translate(-800,-600); // 我们可以平移一下,但是由于之前旋转了所以坐标轴也变了,现在是用负的 painter.drawPixmap(100,100,400,300,pixmap);}
