【Qt】界面优化:绘图API

📅 2026/6/18 16:55:36
【Qt】界面优化:绘图API
个人主页艾莉丝努力练剑❄专栏传送门《C语言》《数据结构与算法》《C/C干货分享学习过程记录》《Linux操作系统编程详解》《笔试/面试常见算法从基础到进阶》《Python干货分享》⭐️为天地立心为生民立命为往圣继绝学为万世开太平 艾莉丝的简介文章目录前言一、绘图API知识图谱二、学习导入语1 ~ Qt绘图API整体介绍1.1 绘图API的作用与使用场景1.2 绘图四大核心类1.2.1 QPainter1.2.2 QPaintDevice1.2.3 QPen1.2.4 QBrush1.3 绘图核心注意事项绘图事件规则1.3.1 paintEvent 事件触发时机1.3.2 禁止在构造函数绘图的原因2 ~ Qt基础图形绘制实操2.1 前置代码准备重写paintEvent函数2.1.1 头文件 widget.h 编写2.1.2 源文件 widget.cpp 基础框架2.1.3 QPainter对象创建规则2.2 各类基础图形绘制2.2.1 绘制线段2.2.2 绘制矩形2.2.3 绘制圆形与椭圆形2.2.4 绘制文本2.3 QPen 画笔详解2.3.1 画笔样式枚举 Qt::PenStyle2.3.2 画笔完整配置代码2.4 QBrush 画刷详解2.4.1 QBrush 构造函数与常用成员函数2.4.2 画刷样式枚举 Qt::BrushStyle2.4.3 画刷完整配置代码2.4.4 多样式填充演示2.5 图形绘制综合实操案例2.5.1 头文件 widget.h2.5.2 源文件 widget.cpp3 ~ Qt图片绘制与图像相关类3.1 QPixmap 绘制图片3.1.1 资源文件准备3.1.2 基础图片绘制指定坐标3.1.3 图片缩放绘制3.1.4 图片旋转与坐标变换3.2 Qt四大图像类整体介绍3.2.1 QPixmap3.2.2 QImage3.2.3 QBitmap3.2.4 QPicture3.3 QPicture 绘图命令录制与回放实操3.3.1 录制绘图命令并保存文件3.3.2 加载文件并回放绘图指令4 ~ 全文核心总结4.1 核心体系与四大基础类4.2 绘图事件核心规则4.3 基础图形绘制重点4.4 画笔与画刷使用要点4.5 图片绘制与四大图像类选型4.6 代码通用规范结尾前言一、绘图API知识图谱二、学习导入语在Qt开发中我们日常使用的按钮、窗口、标签等控件本质都是Qt框架提前封装好的绘图效果。当项目中出现现有标准控件无法实现的自定义界面、特殊图形、个性化视觉效果时就需要手动使用Qt绘图API完成自定义绘制。本文完整梳理Qt绘图体系的全部知识点从四大核心绘图类、绘图事件规则到线段、矩形、圆形、文字等基础图形绘制再到画笔、画刷的样式配置最后延伸至图片绘制、坐标变换以及Qt四大图像类的区别与实操。内容配套完整代码案例、原理解读与易错点说明适合作为知识点复盘、实操查阅的复习资料能够帮助使用者完整梳理Qt绘图API的逻辑链条掌握自定义控件与自定义图形绘制的全流程。1 ~ Qt绘图API整体介绍1.1 绘图API的作用与使用场景Qt中所有自带控件底层都是通过绘图逻辑渲染展示。在绝大多数常规开发场景下我们直接使用Qt封装好的控件即可不需要手动调用绘图API。只有当标准控件无法满足业务需求需要DIY自定义控件、特殊视觉图形、个性化界面效果时才会使用Qt提供的绘图API手动完成绘制工作。1.2 绘图四大核心类Qt绘图体系依托四个核心类实现四类分工明确、相互配合是所有绘图操作的基础1.2.1 QPainter被称作绘图者/画家是执行绘图动作的核心对象。该类提供了大量以drawXXX开头的成员方法支持绘制线段、矩形、圆形、文字、图片等所有图形元素所有绘图动作都由QPainter发起。1.2.2 QPaintDevice被称作画板作用是指定绘图的目标载体也就是QPainter绘制的内容最终展示在哪个对象上。我们常用的QWidget是QPaintDevice的子类因此所有QWidget窗口、控件都可以直接作为画板进行绘图。1.2.3 QPen被称作画笔专门定义线条的外观属性。绘图时所有轮廓线条的颜色、粗细、虚实样式都由QPen对象控制。1.2.4 QBrush被称作画刷专门定义封闭图形内部的填充效果。当绘制矩形、圆形等封闭图形时图形内部的填充颜色、填充纹理、填充图案都由QBrush对象控制。1.3 绘图核心注意事项绘图事件规则Qt绘图绝对不能在QWidget的构造函数中执行所有绘图逻辑必须写在paintEvent事件处理函数中该函数对应QPaintEvent绘图事件。1.3.1 paintEvent 事件触发时机当满足以下任意一种场景时Qt会自动触发paintEvent执行内部的绘图逻辑控件首次创建、界面初始化时控件被其他窗口遮挡遮挡解除后窗口被最小化之后重新还原显示时控件/窗口的大小发生改变时代码中主动调用repaint()或update()成员函数手动触发绘图。1.3.2 禁止在构造函数绘图的原因控件构造阶段窗口/控件的渲染载体还未完成初始化此时执行绘图不会生效。同时窗口遮挡、大小变化、最小化还原等操作会刷新界面构造函数中绘制的内容会被刷新覆盖最终导致界面显示异常。而paintEvent会在界面每一次刷新时自动执行保证绘制内容持续正常展示。2 ~ Qt基础图形绘制实操2.1 前置代码准备重写paintEvent函数想要实现自定义绘图第一步需要在自定义QWidget类中声明并重写paintEvent函数分为头文件和源文件两部分编写。2.1.1 头文件 widget.h 编写#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();// 声明绘图事件函数voidpaintEvent(QPaintEvent*event);private:Ui::Widget*ui;};#endif// WIDGET_H2.1.2 源文件 widget.cpp 基础框架绘图逻辑全部写在paintEvent函数内部同时需要引入QPainter头文件。(void) event;用于消除未使用参数的编译警告QPainter painter(this);创建绘图对象其中this代表当前Widget对象画板。#includewidget.h#includeui_widget.h#includeQPainterWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);}Widget::~Widget(){deleteui;}voidWidget::paintEvent(QPaintEvent*event){(void)event;// 创建绘图对象this为画板当前WidgetQPainterpainter(this);// 所有绘图逻辑写在此处}2.1.3 QPainter对象创建规则QPainter painter(this);是在栈区创建的局部对象函数执行结束后会自动销毁不需要手动调用释放、析构函数使用简单安全。2.2 各类基础图形绘制2.2.1 绘制线段drawLine()是绘制线段的核心方法支持两种传参方式可实现横向、纵向、斜向线段绘制。方式一直接传入坐标数值语法drawLine(起点x, 起点y, 终点x, 终点y)// 横向线段起点(20,20) 终点(200,20)painter.drawLine(20,20,200,20);// 纵向线段起点(20,20) 终点(20,300)painter.drawLine(20,20,20,300);// 斜向线段起点(20,20) 终点(100,300)painter.drawLine(20,20,100,300);方式二传入QPoint坐标对象将起点、终点封装为QPoint对象代码可读性更高// 横向线段两个QPoint对象分别代表起点、终点painter.drawLine(QPoint(20,100),QPoint(200,100));2.2.2 绘制矩形使用drawRect()绘制矩形语法规则drawRect(左上角x, 左上角y, 矩形宽度, 矩形高度)。// 左上角坐标(100,100)宽度300高度200painter.drawRect(100,100,300,200);2.2.3 绘制圆形与椭圆形Qt中没有单独的“画圆”方法drawEllipse()既可以绘制正圆也可以绘制椭圆原理是基于外接矩形绘制函数参数定义外接矩形的位置和尺寸椭圆/圆形会自适应贴合外接矩形。 语法drawEllipse(外接矩形左上角x, 外接矩形左上角y, 宽度, 高度)正圆形外接矩形宽、高数值相等// 外接矩形宽高均为100绘制正圆painter.drawEllipse(200,200,100,100);椭圆形外接矩形宽、高数值不相等// 宽度200、高度50绘制椭圆painter.drawEllipse(200,200,200,50);2.2.4 绘制文本使用drawText()绘制文字同时支持自定义字体样式核心难点是文本基线baseline的理解。基础文本绘制与基线规则语法drawText(横坐标, 纵坐标, 文本内容)横坐标文本最左侧的位置纵坐标文本基线的位置类比英文四线格的第三条线字母默认在基线之上。// 横坐标0基线纵坐标100绘制文字painter.drawText(0,100,hello);若纵坐标数值过小文字会超出可视范围导致无法显示适当增大纵坐标即可正常展示。自定义字体样式 QFont通过QFont类设置字体类型、字号再调用setFont()将字体绑定到绘图对象// 创建字体对象微软雅黑字号24QFontfont(微软雅黑,24);// 绘图对象应用该字体painter.setFont(font);// 绘制文本painter.drawText(0,100,hello);2.3 QPen 画笔详解画笔QPen用于控制所有线条的外观可配置颜色、线条粗细、线条样式三大属性配置完成后必须调用setPen()绑定到QPainter才会生效。2.3.1 画笔样式枚举 Qt::PenStyleQt提供多种预设线条样式常用枚举值如下枚举常量数值样式说明Qt::NoPen0无线条Qt::SolidLine1实线默认样式Qt::DashLine2虚线短划线Qt::DotLine3点线Qt::DashDotLine4点划线Qt::DashDotDotLine5一划两点式线条2.3.2 画笔完整配置代码// 1. 创建画笔对象QPen pen;// 2. 设置线条颜色RGB(255,0,0) 红色pen.setColor(QColor(255,0,0));// 3. 设置线条粗细宽度5像素pen.setWidth(5);// 4. 设置线条样式虚线pen.setStyle(Qt::DashLine);// 5. 关键将画笔绑定到绘图对象配置才会生效painter.setPen(pen);// 绑定后绘制的图形都会使用当前画笔样式painter.drawLine(20,20,200,20);2.4 QBrush 画刷详解画刷QBrush用于控制封闭图形矩形、圆形、椭圆的内部填充效果可配置填充颜色、填充样式。默认状态下画刷为Qt::NoBrush无填充因此仅设置颜色无法实现填充必须手动指定填充样式。2.4.1 QBrush 构造函数与常用成员函数QBrush提供多种重载构造函数支持直接通过颜色、样式、图片创建画刷核心成员函数setColor()设置填充颜色setStyle()设置填充样式setTexture()/setTextureImage()使用图片作为填充纹理。2.4.2 画刷样式枚举 Qt::BrushStyleQt内置丰富的填充样式常用类型Qt::SolidPattern实心纯色填充最常用Qt::Dense1Pattern ~ Qt::Dense7Pattern不同密度的点阵填充Qt::HorPattern水平线条填充Qt::VerPattern垂直线条填充Qt::CrossPattern网格交叉线填充渐变类样式线性渐变、径向渐变、锥形渐变Qt::TexturePattern图片纹理填充。2.4.3 画刷完整配置代码// 1. 创建画刷对象QBrush brush;// 2. 设置填充颜色RGB(0,255,0) 绿色brush.setColor(QColor(0,255,0));// 3. 设置填充样式实心填充必须配置否则无填充效果brush.setStyle(Qt::SolidPattern);// 4. 将画刷绑定到绘图对象painter.setBrush(brush);// 绘制椭圆内部会被绿色实心填充painter.drawEllipse(200,200,400,100);2.4.4 多样式填充演示更换setStyle()的参数即可切换不同填充效果// 点阵填充brush.setStyle(Qt::Dense1Pattern);// 网格交叉线填充brush.setStyle(Qt::CrossPattern);2.5 图形绘制综合实操案例整合画笔、画刷、椭圆绘制的完整可运行代码包含头文件与源文件2.5.1 头文件 widget.h#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();voidpaintEvent(QPaintEvent*event);private:Ui::Widget*ui;};#endif// WIDGET_H2.5.2 源文件 widget.cpp#includewidget.h#includeui_widget.h#includeQPainterWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);}Widget::~Widget(){deleteui;}voidWidget::paintEvent(QPaintEvent*event){(void)event;QPainterpainter(this);// 配置画笔橙红色、5像素粗、虚线QPen pen;pen.setColor(QColor(255,122,23));pen.setWidth(5);pen.setStyle(Qt::DashLine);painter.setPen(pen);// 配置画刷土黄色、网格填充QBrush brush;brush.setColor(QColor(155,122,44));brush.setStyle(Qt::CrossPattern);painter.setBrush(brush);// 绘制椭圆外接矩形宽100高200painter.drawEllipse(200,200,100,200);}3 ~ Qt图片绘制与图像相关类3.1 QPixmap 绘制图片QPixmap是Qt专门为屏幕图像显示优化的类也是界面中绘制图片的首选。绘制图片前需要将图片添加到Qt资源文件.qrc中通过资源路径加载图片。3.1.1 资源文件准备在项目中新建资源文件resoures.qrc添加前缀、导入本地图片文件如cat.jpg图片资源路径格式:/图片文件名。3.1.2 基础图片绘制指定坐标使用drawPixmap(图片x坐标, 图片y坐标, QPixmap对象)绘制图片图片左上角对齐指定坐标voidWidget::paintEvent(QPaintEvent*event){(void)event;QPainterpainter(this);// 加载资源中的图片QPixmappixmap(:/cat.jpg);// 图片左上角对齐窗口(0,0)位置painter.drawPixmap(0,0,pixmap);// 图片左上角对齐窗口(100,100)位置painter.drawPixmap(100,100,pixmap);}3.1.3 图片缩放绘制重载drawPixmap方法新增宽度、高度参数实现图片缩放展示 语法drawPixmap(x, y, 缩放宽度, 缩放高度, QPixmap对象)// 在(100,100)位置绘制图片缩放到宽400、高300painter.drawPixmap(100,100,400,300,pixmap);3.1.4 图片旋转与坐标变换图片旋转的本质是旋转QPainter绘图坐标系Qt提供rotate()旋转方法、translate()坐标平移方法二者配合使用解决旋转偏移问题。旋转原理与问题painter.rotate(角度)默认以窗口坐标系原点(0,0)为中心旋转。若直接旋转图片图片会转出可视区域导致界面看不到内容。坐标平移修正偏移使用translate(x偏移, y偏移)平移坐标系原点将旋转中心调整到可视区域内。窗口向右为X正方向、向下为Y正方向反向平移使用负数参数。旋转平移完整代码voidWidget::paintEvent(QPaintEvent*event){(void)event;QPainterpainter(this);QPixmappixmap(:/wife.png);// 坐标系整体旋转180度painter.rotate(180);// 平移坐标系原点修正旋转后图片位置painter.translate(-800,-600);// 绘制缩放后的图片painter.drawPixmap(100,100,400,500,pixmap);}3.2 Qt四大图像类整体介绍Qt提供四个专门处理图像数据的类四类底层均为QPaintDevice画板适用场景各有区分开发中最常用QPixmap和QImage。3.2.1 QPixmap针对屏幕显示做深度优化渲染效率高是UI界面展示图片的首选不适合做复杂像素编辑、大量IO读写操作。3.2.2 QImage针对文件IO读写、像素级编辑优化支持直接访问、修改图片每一个像素点适合图片处理、图像算法开发屏幕渲染效率弱于QPixmap。3.2.3 QBitmapQPixmap的子类是特殊的位图仅支持黑白两种颜色颜色深度为1多用于制作图标、遮罩、光标等二值图像。3.2.4 QPicture功能区别于普通图片类核心作用是录制与回放QPainter绘图命令。它不会保存图片像素而是记录所有绘图动作画线段、画圆、文字等指令文件体积极小类似游戏录像只记录操作而非录制画面。3.3 QPicture 绘图命令录制与回放实操3.3.1 录制绘图命令并保存文件在构造函数中完成绘图命令录制将指令保存为本地文件#includewidget.h#includeui_widget.h#includeQPainter#includeQPictureWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);// 创建绘图命令记录对象QPicture pic;QPainter painter;// 开始录制将绘图目标绑定为QPicturepainter.begin(pic);// 配置画笔、绘制图形录制动作painter.setPen(QPen(Qt::red));painter.drawEllipse(QPoint(200,200),100,100);// 结束录制painter.end();// 将录制的绘图指令保存到本地文件pic.save(C:\\Users\\Lenovo\\Desktop\\Test_Pic\\pic.pic);}Widget::~Widget(){deleteui;}3.3.2 加载文件并回放绘图指令在paintEvent中加载保存的指令文件回放所有绘图动作voidWidget::paintEvent(QPaintEvent*){QPainterpainter(this);QPicture pic;// 加载本地保存的绘图指令文件pic.load(C:\\Users\\Lenovo\\Desktop\\Test_Pic\\pic.pic);// 回放绘图指令在窗口(0,0)位置执行绘制painter.drawPicture(0,0,pic);}补充说明QPicture是Qt私有格式仅能在Qt程序中加载回放无法使用第三方图片编辑器打开。4 ~ 全文核心总结4.1 核心体系与四大基础类整体定位Qt绘图API用于实现自定义控件、特殊图形效果常规开发使用标准控件即可无需手动绘图四大核心类分工QPainter绘图者执行所有drawXXX绘图方法核心动作执行者QPaintDevice画板绘图目标载体QWidget是其子类所有窗口均可作为画板QPen画笔控制线条的颜色、粗细、虚实样式QBrush画刷控制封闭图形的内部填充颜色、纹理、图案默认无填充。4.2 绘图事件核心规则绘图位置强制要求所有绘图逻辑必须写在paintEvent(QPaintEvent *event)函数中禁止在构造函数绘图paintEvent触发场景控件初始化、遮挡解除、窗口最小化还原、控件大小改变、主动调用repaint()/update()五种场景自动触发重绘QPainter对象建议在栈区创建局部对象无需手动释放。4.3 基础图形绘制重点线段drawLine支持坐标直接传参、QPoint对象传参可绘制横、竖、斜线矩形drawRect(左上角x, 左上角y, 宽, 高)圆/椭圆drawEllipse基于外接矩形绘制宽高相等为正圆不等为椭圆文本drawText纵坐标为文本基线基线位置过低会导致文字不可见使用QFont设置字体类型与字号通过setFont绑定到绘图对象。4.4 画笔与画刷使用要点QPen配置颜色、线宽、样式后必须调用setPen()绑定到QPainter才生效常用样式包括实线、虚线、点线等QBrush仅设置颜色无法填充图形必须调用**setStyle()**指定填充样式支持实心、点阵、网格、渐变、图片纹理等多种填充模式。4.5 图片绘制与四大图像类选型QPixmap界面图片显示首选配合资源文件加载图片drawPixmap支持定位、缩放展示图片坐标变换rotate()旋转坐标系默认绕原点(0,0)旋转translate()平移坐标系修正旋转偏移二者配合实现图片旋转展示四类图像类选型建议界面展示图片 → 优先QPixmap图片读写、像素编辑 → 优先QImage黑白图标、遮罩 → 使用QBitmap记录/回放绘图动作、精简绘图指令 → 使用QPicture。4.6 代码通用规范所有绘图代码均需引入头文件QPainter、QPixmap、QPicture等资源图片必须添加到.qrc资源文件使用:/资源名格式加载QPicture仅Qt内部可用属于私有绘图指令格式不兼容第三方图片工具。结尾uu们本文的内容到这里就全部结束了艾莉丝在这里再次感谢您的阅读艾莉丝努力练剑C/C Linux 底层探索者 | 一个正在努力练剑的技术博主【关注】跟随我一起深耕技术领域见证每一次成长。❤️【点赞】让优质内容被更多人看见让知识传递更有力量。⭐【收藏】把核心知识点存好在需要时随时查、随时用。【评论】分享你的经验或疑问评论区一起交流避坑不要忘记给博主“一键四连”哦“今日练剑达成”“技术之路难免有困惑但同行的人会让前进更有方向。”结语希望对学习Linux相关内容的uu有所帮助不要忘记给博主“一键四连”哦往期回顾【QT】界面优化QSS博主在这里放了一只小狗大家看完了摸摸小狗放松一下吧૮₍ ˶ ˊ ᴥ ˋ˶₎ა