QT-界面优化(下)
本文介绍了Qt绘图API的核心使用方法和实践技巧。主要内容包括:1)Qt绘图体系四大核心类(QPainter、QPaintDevice、QPen、QBrush)的功能分工;2)正确的绘图时机应在paintEvent事件中;3)图形绘制基础(线段、矩形、椭圆);4)样式定制(画笔样式、填充效果);5)文字绘制注意事项;6)图片显示与处理(原始显示、缩放、旋转)。文章通过代码示例详细演示了各项功能的具
目录
前言
Qt 提供的标准控件能满足大部分开发需求,但当需要个性化 UI 时,绘图 API 是实现自定义控件 / 效果的关键。本文从核心类、绘图时机到实战示例,带你快速掌握 Qt 绘图的基础逻辑。
绘图 API 的核心角色
Qt 绘图体系由 4 个核心类组成,分工明确:
| 类名 | 角色 | 说明 |
|---|---|---|
QPainter |
绘者 / 画家 | 提供 drawXXX 方法(如 drawLine/drawRect),负责执行绘图操作。 |
QPaintDevice |
画板 | 绘图的 “载体”,QWidget 是其常见子类(即可以直接在控件上绘图)。 |
QPen |
画笔 | 控制绘制图形的轮廓样式(颜色、粗细、线条类型)。 |
QBrush |
画刷 | 控制图形的填充样式(颜色、渐变、纹理)。 |
绘图的正确时机:paintEvent 事件
Qt 中绘图操作不能直接写在控件构造函数中(此时控件未完成初始化,绘图会失效),而要放在 paintEvent 事件处理函数中。
paintEvent 会在以下场景自动触发:
- 控件首次创建时;
- 控件被遮挡后解除遮挡;
- 窗口最小化后还原;
- 控件大小改变时;
- 主动调用
repaint()/update()时。
绘制图形
以下示例展示如何在自定义 Widget 中重写 paintEvent,绘制线段、矩形和椭圆:
// widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
// 重写 paintEvent 事件处理函数
void paintEvent(QPaintEvent *event) override;
};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"
#include <QPainter>
#include <QPoint>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setFixedSize(400, 400); // 设置控件大小
}
Widget::~Widget()
{
}
void Widget::paintEvent(QPaintEvent *event)
{
(void)event; // 忽略事件参数
// 1. 创建 QPainter 对象,指定“画板”为当前 Widget
QPainter painter(this);
// 2. 绘制线段
painter.drawLine(20, 20, 200, 20); // 从 (20,20) 到 (200,20)
painter.drawLine(QPoint(20, 100), QPoint(200, 100)); // 用 QPoint 传坐标
// 3. 绘制矩形(x,y,宽度,高度)
painter.drawRect(100, 100, 300, 200);
// 4. 绘制椭圆(x,y,宽度,高度)
painter.drawEllipse(200, 200, 200, 50);
}
用 QPen/QBrush 定制样式
通过 QPen 和 QBrush,可以给图形添加轮廓和填充效果:
void Widget::paintEvent(QPaintEvent *event)
{
(void)event;
QPainter painter(this);
// 1. 设置画笔(红色、2px 实线)
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(2);
pen.setStyle(Qt::SolidLine);
painter.setPen(pen);
// 2. 设置画刷(蓝色填充)
QBrush brush;
brush.setColor(Qt::blue);
brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush);
// 3. 绘制带样式的矩形
painter.drawRect(50, 50, 200, 150);
画笔(QPen)的样式控制
QPen 不仅能设置颜色、粗细,还能控制线条样式(如实线、虚线),常用样式包括:
| 样式常量 | 效果描述 |
|---|---|
Qt::SolidLine |
实线(默认) |
Qt::DashLine |
虚线(短横线) |
Qt::DotLine |
点线 |
Qt::DashDotLine |
点划线(短横 + 点) |
Qt::DashDotDotLine |
双点划线 |
结合QBrush使用
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
void Widget::paintEvent(QPaintEvent* event)
{
(void)event; // 忽略事件参数,避免编译器警告
// 1. 创建画家对象,指定绘图载体为当前Widget
QPainter painter(this);
// 2. 创建并设置画刷(绘制图形前设置)
QBrush brush;
brush.setColor(QColor(100, 0, 100)); // RGB 紫色
brush.setStyle(Qt::CrossPattern); // 十字交叉填充样式
painter.setBrush(brush); // 将画刷应用到画家
// 3. 绘制矩形(此时会使用上述画刷填充)
painter.drawRect(100, 100, 300, 200);
}
Widget::~Widget()
{
delete ui;
}
效果:

绘制文字(drawText)
通过 QPainter::drawText 可在控件上绘制文字,需注意坐标的含义:
// 创建字体:字体为“微软雅黑”,大小20
QFont font("微软雅黑", 20);
// 将字体设置到画家对象中
painter.setFont(font);
painter.drawText(0, 100, "hello");
- 横坐标
0:文字最左侧的位置; - 纵坐标
100:文字的基线(baseline)位置(即文字底部对齐的基准线,不是文字的顶部 / 底部坐标)。

绘制图片
在 Qt 中,QPixmap 是专门用于在屏幕上显示图像的类,对显示优化友好。通过 QPainter::drawPixmap 方法可以将图片绘制到控件上,支持基础显示、缩放、旋转等操作。
1 基础绘制:显示原始图片
最基本的图片绘制步骤如下:
void Widget::paintEvent(QPaintEvent *event)
{
(void)event;
QPainter painter(this);
// 1. 加载图片(路径需根据实际图片位置调整)
QPixmap pixmap(":/images/cat.jpg"); // 假设图片放在资源文件中
// 2. 绘制图片:左上角坐标 (50, 50),显示原始大小
painter.drawPixmap(50, 50, pixmap);
}
关键说明:
- 图片路径:若图片在项目目录下,可直接写相对路径(如
"./cat.jpg");若添加到 Qt 资源文件(.qrc),需用资源路径(如":/images/cat.jpg"); - 坐标含义:
drawPixmap(50, 50, pixmap)表示图片左上角对齐控件的(50, 50)坐标,图片尺寸保持原始大小。
2 进阶:缩放与旋转图片
QPixmap 支持绘制时调整图片大小,结合 QPainter 的变换功能还能实现旋转效果。
示例:缩放并旋转图片
void Widget::paintEvent(QPaintEvent *event)
{
(void)event;
QPainter painter(this);
// 加载图片
QPixmap pixmap(":/images/cat.jpg");
if (pixmap.isNull()) { // 检查图片是否加载成功
painter.drawText(100, 100, "图片加载失败");
return;
}
// 1. 缩放绘制:将图片缩放到 (300x200) 尺寸,左上角坐标 (100, 100)
painter.drawPixmap(100, 100, 300, 200, pixmap);
// 2. 旋转绘制:先保存画家状态,避免影响后续绘图
painter.save();
// 旋转30度(原点默认在控件左上角,旋转会导致图片偏移,需调整坐标)
painter.rotate(30);
// 平移坐标,使旋转中心对准目标位置(避免图片超出可视区域)
painter.translate(400, -200);
// 绘制旋转后的图片(尺寸 200x150)
painter.drawPixmap(0, 0, 200, 150, pixmap);
// 恢复画家状态(清除旋转、平移等变换)
painter.restore();
}
核心技巧:
- 缩放:
drawPixmap(x, y, width, height, pixmap)中,width和height为目标尺寸,图片会自动拉伸 / 压缩适配; - 旋转:通过
painter.rotate(角度)实现,旋转原点默认是控件左上角,因此旋转后常需用translate(x, y)调整坐标,避免图片偏移到可视区域外; - 状态保存:
save()和restore()用于隔离不同绘图操作的状态(如旋转、画笔样式),防止相互干扰。
3 注意事项
- 图片格式:
QPixmap支持常见格式(JPG、PNG、BMP 等),但加载失败时isNull()会返回true,建议添加判断; - 资源管理:大型图片建议通过资源文件(
.qrc)管理,避免路径依赖问题; - 性能:
QPixmap适合显示静态图片,若需频繁修改像素(如滤镜处理),建议先用QImage处理后再转为QPixmap显示。
通过 QPixmap 和 QPainter 的结合,可轻松实现图片的各种显示效果,是自定义 UI 中展示图像的核心工具。
总结
Qt 绘图 API 是自定义控件的基础,核心要点是:
- 核心类:
QPainter(绘图)、QPaintDevice(载体)、QPen(轮廓)、QBrush(填充); - 绘图时机:必须在
paintEvent中执行,自动响应控件状态变化; - 实用场景:当标准控件无法满足需求时(如自定义仪表盘、特殊形状按钮),通过绘图 API 实现个性化效果。
更多推荐


所有评论(0)