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框架。

相关推荐
凯子坚持 c1 小时前
在 Visual Studio 2019 中配置 Qt 插件开发环境:编译原理 + 底层逻辑解析
ide·qt·visual studio
枫叶丹42 小时前
【Qt开发】Qt系统(八)-> Qt UDP Socket
c语言·开发语言·c++·qt·udp
艾莉丝努力练剑3 小时前
【QT】Qt 从零上手:Hello World、项目文件与实战避坑指南
linux·运维·开发语言·c++·qt·继承·qt5
prettyxian3 小时前
【QT】信号与槽:自定义信号、参数传递与Lambda
开发语言·qt
初次见面我叫泰隆21 小时前
Qt——1、初识Qt
开发语言·c++·qt
一只小bit1 天前
Qt 事件:覆盖介绍、处理、各种类型及运用全详解
前端·c++·qt·cpp
不会c嘎嘎1 天前
QT中的事件机制
开发语言·qt
涛起云永1 天前
Qt 源码编译 -- obj文件无法找到
开发语言·qt
郝学胜-神的一滴1 天前
Qt自定义TabWidget:实现左侧标签与水平文本布局
开发语言·c++·qt·程序人生
划水的code搬运工小李1 天前
VOFA修改数据解析GPCHC
开发语言·qt