Qt面试题合集(四)

6.Qt绘图系统的核心类有哪些?区别是什么?

Qt绘图系统提供了多个类用于2D图形绘制,主要分为基于QPainter的立即模式基于Graphics View的场景图模式两大体系。

1. 核心类概览

立即模式绘图(Immediate Mode)

  • QPainter - 绘图引擎,执行实际绘制操作
  • QPaintDevice - 绘图设备的抽象基类
  • QPaintEngine - 底层绘图引擎接口
  • QPen - 画笔(轮廓样式)
  • QBrush - 画刷(填充样式)
  • QPainterPath - 复杂路径定义

场景图模式(Scene Graph)

  • QGraphicsView - 视图窗口
  • QGraphicsScene - 场景容器
  • QGraphicsItem - 图形项基类
  • QGraphicsItemGroup - 图形项组

其他重要类

  • QImage - 图像处理
  • QPixmap - 像素图显示
  • QPicture - 绘图命令记录

2. 主要类详解与区别

QPainter vs QGraphicsView

特性 QPainter QGraphicsView
绘制模式 立即模式,立即执行绘制命令 保留模式,维护场景图
性能 简单绘制性能好 复杂场景管理性能好
内存使用 较高(维护场景数据)
交互支持 需要手动处理 内置交互(选择、拖动等)
适用场景 简单绘图、自定义控件、图像处理 复杂图形界面、CAD、图表、游戏
坐标系 物理坐标系 逻辑坐标系(支持变换)

QPaintDevice 子类对比

用途 特点
QWidget 控件绘图 双缓冲,支持部分更新
QPixmap 屏幕显示 平台优化,适合显示操作
QImage 图像处理 独立于硬件,像素级访问
QPicture 记录回放 保存和重现绘制命令

QPixmap vs QImage

特性 QPixmap QImage
存储位置 显存/GPU 内存/CPU
像素访问 慢(需要转换) 快(直接访问)
硬件加速 支持 不支持
平台依赖
文件格式 有限 丰富(BMP、PNG、JPEG等)
适用场景 界面显示 图像处理、修改、保存

3. 使用示例对比

QPainter 立即模式示例

cpp

c++ 复制代码
// 在QWidget中绘制
void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);  // 在widget上绘制
    
    // 设置画笔和画刷
    painter.setPen(QPen(Qt::blue, 2));
    painter.setBrush(QBrush(Qt::yellow));
    
    // 绘制图形
    painter.drawRect(10, 10, 100, 50);
    painter.drawEllipse(50, 50, 60, 60);
    
    // 绘制文本
    painter.drawText(20, 90, "QPainter示例");
}

QGraphicsView 场景图示例

cpp

c++ 复制代码
// 创建场景和视图
QGraphicsScene *scene = new QGraphicsScene();
QGraphicsView *view = new QGraphicsView(scene);

// 添加图形项
QGraphicsRectItem *rect = scene->addRect(10, 10, 100, 50);
rect->setBrush(Qt::yellow);
rect->setFlag(QGraphicsItem::ItemIsMovable);  // 可拖动

QGraphicsEllipseItem *ellipse = scene->addEllipse(50, 50, 60, 60);
ellipse->setBrush(Qt::blue);
ellipse->setFlag(QGraphicsItem::ItemIsSelectable);  // 可选择

// 添加文本
QGraphicsTextItem *text = scene->addText("Graphics View示例");
text->setPos(20, 90);

4. 绘图系统的层次结构

text

复制代码
┌─────────────────────────────────────┐
│     应用程序/自定义控件              │
├─────────────────────────────────────┤
│   QPainter(绘图引擎)               │
├─────────────────────────────────────┤
│   QPaintDevice(绘图设备抽象)       │
│   ├─ QWidget(控件)                 │
│   ├─ QPixmap(像素图)               │
│   ├─ QImage(图像)                  │
│   └─ QPicture(绘图命令)            │
├─────────────────────────────────────┤
│   QPaintEngine(平台相关实现)       │
│   ├─ Raster(光栅)                 │
│   ├─ OpenGL(OpenGL)               │
│   └─ OpenVG(矢量)                 │
└─────────────────────────────────────┘

5. 场景图(Graphics View)架构

text

复制代码
┌─────────────────────────────────────┐
│     QGraphicsView(视图)            │
│     显示和管理场景                   │
├─────────────────────────────────────┤
│     QGraphicsScene(场景)           │
│     管理所有图形项                   │
├─────────────────────────────────────┤
│     QGraphicsItem(图形项)          │
│     ├─ QGraphicsRectItem            │
│     ├─ QGraphicsEllipseItem         │
│     ├─ QGraphicsTextItem            │
│     ├─ QGraphicsPixmapItem          │
│     ├─ QGraphicsPathItem            │
│     └─ 自定义QGraphicsItem          │
└─────────────────────────────────────┘

6. 选择指南

使用 QPainter 的情况:

  1. 简单绘图需求
  2. 自定义控件绘制
  3. 图像处理操作
  4. 需要直接控制绘制过程
  5. 性能要求高且场景简单

使用 Graphics View 的情况:

  1. 大量图形项需要管理
  2. 需要交互(选择、拖动、缩放)
  3. 复杂场景变换
  4. 需要分层和分组
  5. 图形项需要独立逻辑

7. 高级特性对比

特性 QPainter Graphics View
抗锯齿 setRenderHint(QPainter::Antialiasing) setRenderHint(QPainter::Antialiasing)
变换 支持(缩放、旋转、平移) 支持(场景和视图级别)
裁剪 setClipRect(), setClipPath() 视图裁剪,项级别裁剪
双缓冲 默认(在QWidget中) 默认支持
动画 需手动实现 有QGraphicsItemAnimation支持
碰撞检测 需手动实现 内置碰撞检测

8. 性能优化建议

QPainter 优化:

cpp

C++ 复制代码
void paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 按需使用
    
    // 只绘制需要更新的区域
    QRect rectToUpdate = event->rect();
    
    // 避免不必要的状态改变
    painter.setPen(QPen(Qt::black, 1));
    // 多次绘制...
}

Graphics View 优化:

cpp

c++ 复制代码
QGraphicsView *view = new QGraphicsView(scene);
view->setRenderHint(QPainter::Antialiasing);  // 选择性使用
view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);  // 智能更新
view->setOptimizationFlag(QGraphicsView::DontSavePainterState);  // 优化标志

总结

Qt绘图系统提供了两套互补的解决方案:

  • QPainter:轻量、灵活,适合简单绘制和自定义控件
  • Graphics View:功能完整,适合复杂交互式图形应用

在实际开发中,可以根据需求选择或组合使用这两种方式。例如,可以在自定义控件中使用QPainter进行绘制,而在需要管理大量交互式图形时使用Graphics View框架。

相关推荐
GanGuaGua2 小时前
JsonRpc:手搓一个高性能Rpc服务(应用篇)
qt·网络协议·rpc
追烽少年x5 小时前
Qt中线程同步类介绍(一)
qt
树欲静而风不止慢一点吧6 小时前
Qt5/6版本对应的Emscripten版本
开发语言·qt
LYOBOYI1237 小时前
qt的事件传播机制
java·前端·qt
prettyxian9 小时前
【QT】Qt从零入门指南:创建你的第一个GUI程序
开发语言·qt
不会c嘎嘎10 小时前
QT中的常用控件(一)
开发语言·qt
枫叶丹413 小时前
【Qt开发】Qt系统(一)-> 定时器 QTimerEvent 和 QTimer
c语言·开发语言·数据库·c++·qt·系统架构
林政硕(Cohen0415)14 小时前
ARM Linux Qt Widget 虚拟键盘输入法移植
linux·arm开发·qt·键盘·输入法
养一回月亮!20 小时前
使用Qt实现简单绘图板:鼠标绘制与擦除功能详解
开发语言·qt