qt c++ 场景图架构的类都有什么

qt c++ 场景图架构的类都有什么

1.qt c++ 场景图架构的类都有什么

在Qt的C++场景图架构中,不同模块(如Qt WidgetsQt QuickQt 3D)提供了各自的场景图实现,核心类及其功能如下:

1. Qt Widgets - Graphics View框架(2D场景图)

  • QGraphicsScene:场景容器,管理所有图形项(QGraphicsItem),负责碰撞检测、事件分发、打印渲染等。支持动态添加/删除项,通过addItem()removeItem()管理。
  • QGraphicsView:视图窗口,显示场景内容。支持缩放、平移、旋转(通过transform()),处理鼠标/键盘事件并映射到场景坐标。可启用OpenGL加速(通过setViewport(QGLWidget*))。
  • QGraphicsItem:图形项基类,包括:
    • 预定义项:QGraphicsRectItem(矩形)、QGraphicsEllipseItem(椭圆)、QGraphicsPixmapItem(图片)、QGraphicsTextItem(文本)、QGraphicsPathItem(路径)等。
    • 自定义项:继承QGraphicsItem并重写boundingRect()(边界矩形)和paint()(绘制逻辑),支持拖拽、选择、分组(QGraphicsItemGroup)。
  • 辅助类
    • QGraphicsProxyWidget:嵌入QWidget到场景中(如按钮、输入框)。
    • QGraphicsLayout/QGraphicsLayoutItem:布局管理(如水平/垂直布局)。
    • QGraphScene::BSPTreeIndex:通过二进制空间划分树优化大规模项的碰撞检测。

2. Qt Quick - Scene Graph(2D/3D混合渲染)

  • QQuickWindow:场景图渲染窗口,管理渲染线程和节点树。通过setRenderTarget()支持离屏渲染。
  • QSGNode:场景图节点基类,构建渲染树。子类包括:
    • QSGGeometryNode:几何图形节点(顶点、材质),用于绘制形状。
    • QSGOpacityNode:透明度节点,控制子节点透明度。
    • QSGTransformNode:变换节点,支持平移、旋转、缩放。
    • QSGClipNode:裁剪节点,实现局部渲染区域限制。
  • QQuickItem:场景中的基本元素,通过重写updatePaintNode()添加自定义图形节点。需设置ItemHasContents标志。
  • 材质与着色器
    • QSGMaterial:封装渲染状态(如着色器程序)。
    • QSGFlatColorMaterial:纯色材质;QSGOpaqueTextureMaterial:纹理材质。
    • QSGMaterialShader:跨图形API的着色器实现。

3. Qt 3D / Qt Quick 3D(3D场景图)

  • QEntity:3D场景中的实体(如模型、灯光、相机),可附加组件(QComponent)。
  • QComponent:功能模块(如QCameraQMeshQMaterialQTransform),附加到实体上定义其行为。
  • QScene:场景根节点,管理实体和组件的层级关系。
  • Qt Quick 3D:通过View3D定义渲染视图,结合Layer节点构建场景图。SceneEnvironment控制光照、雾效等全局参数。

架构特点

  • 坐标系:场景坐标(全局)、视图坐标(窗口)、图形项局部坐标(自定义)。
  • 事件传播:事件从视图→场景→图形项,支持碰撞检测(collidingItems())和事件过滤。
  • 性能优化:BSP树索引、批量渲染(减少状态切换)、多视图支持(同一场景多窗口查看)。

这些类共同构成了Qt的场景图架构,支持从简单的2D图形到复杂的3D场景的渲染与交互。具体使用需根据项目需求选择模块(如Widgets适合桌面应用,Quick适合动态UI,3D适合三维渲染)。

2.QGraphicsScene

QGraphicsScene 是 Qt 框架中用于管理 2D 图形项(QGraphicsItem)的场景类,是 Qt Graphics View Framework 的核心组成部分之一。它与 QGraphicsView(视图)和 QGraphicsItem(图形项)共同构成一个强大的 2D 图形渲染与交互系统。


一、基本概念

  • QGraphicsScene:表示一个场景,用于容纳和管理大量的 2D 图形项(如矩形、椭圆、文本、自定义图形等)。
  • QGraphicsView:是一个可滚动的视口(viewport),用于显示 QGraphicsScene 的一部分。
  • QGraphicsItem:代表场景中的单个图形元素,可以是 Qt 提供的标准项(如 QGraphicsRectItemQGraphicsEllipseItem),也可以是自定义子类。

三者关系:

QGraphicsView → 显示 → QGraphicsScene → 管理 → 多个 QGraphicsItem 

二、主要功能

1. 图形项管理

  • 添加/删除图形项(addItem(), removeItem()
  • 查找图形项(items(), itemAt()
  • 分组(通过 QGraphicsItemGroup

2. 坐标系统

  • 场景使用浮点坐标(qreal),支持高精度定位。
  • 每个 QGraphicsItem 有自己的局部坐标系,可通过 mapToScene() / mapFromScene() 转换。

3. 事件处理

  • 支持鼠标、键盘、拖拽等事件的分发。
  • 事件首先由 QGraphicsView 接收,然后转发给场景,再由场景分发给合适的 QGraphicsItem

4. 渲染与性能优化

  • 使用 BSP 树(Binary Space Partitioning)加速图形项查找和渲染。
  • 支持裁剪(只渲染可见区域)、缓存等机制提升性能。

5. 选择与焦点

  • 支持多选(setSelectionArea())、键盘焦点项(setFocusItem())。
  • 可设置选择模式(setSelectionMode())。

三、常用 API(C++)

创建场景

QGraphicsScene *scene = new QGraphicsScene(this); scene->setSceneRect(0, 0, 800, 600); // 设置场景范围 

添加图形项

QGraphicsRectItem *rect = scene->addRect(100, 100, 200, 100, QPen(Qt::black), QBrush(Qt::blue)); QGraphicsEllipseItem *ellipse = scene->addEllipse(300, 200, 100, 100, QPen(Qt::red), QBrush(Qt::yellow)); QGraphicsTextItem *text = scene->addText("Hello QGraphicsScene!"); text->setPos(50, 50); 

自定义图形项(继承 QGraphicsItem)

class MyItem : public QGraphicsItem { public: QRectF boundingRect() const override { return QRectF(-10, -10, 20, 20); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter->drawEllipse(boundingRect()); } }; // 使用 MyItem *myItem = new MyItem(); scene->addItem(myItem); myItem->setPos(400, 300); 

事件处理(在自定义项中)

void mousePressEvent(QGraphicsSceneMouseEvent *event) override { qDebug() << "Item clicked at:" << event->pos(); QGraphicsItem::mousePressEvent(event); } 

连接视图

QGraphicsView *view = new QGraphicsView(scene, this); view->setRenderHint(QPainter::Antialiasing); // 抗锯齿 view->show(); 

选择与交互

scene->setSelectionArea(QPainterPath()); // 清除选择 scene->setSelectionMode(QGraphicsScene::MultiSelection); // 多选模式 

坐标转换示例

// 将视图坐标转为场景坐标 QPoint viewPos = view->mapFromGlobal(QCursor::pos()); QPointF scenePos = view->mapToScene(viewPos); // 获取该位置的图形项 QGraphicsItem *item = scene->itemAt(scenePos, view->transform()); 

四、高级特性

1. 动画支持

配合 QPropertyAnimationQGraphicsItemAnimation(旧版)实现动画。

2. 拖放(Drag & Drop)

重写 dragEnterEventdropEvent 等方法支持拖放操作。

3. 层次结构(父子关系)

childItem->setParentItem(parentItem); // 建立父子关系 

子项坐标相对于父项,变换会级联。

4. 碰撞检测

通过 collidingItems() 检测与其他项的碰撞(基于 shape()boundingRect())。


五、性能建议

  • 避免频繁调用 update(),尽量批量操作。
  • 对静态内容使用 setCacheMode(QGraphicsItem::DeviceCoordinateCache)
  • 使用 setItemIndexMethod(QGraphicsScene::BspTreeIndex)(默认)加速查找。
  • 大量项时考虑分页或 LOD(Level of Detail)策略。

六、完整最小示例(C++)

#include <QApplication> #include <QGraphicsScene> #include <QGraphicsView> #include <QGraphicsRectItem> int main(int argc, char *argv[]) { QApplication app(argc, argv); QGraphicsScene scene; scene.setSceneRect(0, 0, 400, 300); QGraphicsRectItem *rect = scene.addRect(50, 50, 100, 80, QPen(Qt::black), QBrush(Qt::green)); rect->setFlag(QGraphicsItem::ItemIsMovable); // 可移动 rect->setFlag(QGraphicsItem::ItemIsSelectable); // 可选择 QGraphicsView view(&scene); view.setRenderHint(QPainter::Antialiasing); view.setWindowTitle("QGraphicsScene Example"); view.resize(500, 400); view.show(); return app.exec(); } 

七、常见问题

问题解决方案
图形项不显示检查是否调用了 addItem(),场景矩形是否包含该项
无法交互确保设置了 ItemIsMovableItemIsSelectable 等标志
坐标混乱理解局部坐标 vs 场景坐标,善用 mapToScene()
性能差启用缓存、减少重绘、使用 BSP 索引

八、参考文档


如需进一步了解自定义图形项、动画、拖拽、缩放/平移控制等内容,可继续提问!

3.QGraphicsView

QGraphicsView 是 Qt 框架中用于显示和交互 QGraphicsScene 中图形项(QGraphicsItem)的视图组件。它是 Qt Graphics View Framework 的三大核心类之一,另外两个是:

  • QGraphicsScene:场景容器,管理大量 2D 图形项。
  • QGraphicsItem:所有图形项的基类(如矩形、椭圆、自定义图形等)。

一、基本概念

1. 架构关系

QGraphicsItem(s) → QGraphicsScene → QGraphicsView 
  • QGraphicsItem:表示一个可绘制的对象(如点、线、图片、文本等),可以响应鼠标、键盘事件。
  • QGraphicsScene:作为“画布”,容纳并管理多个 QGraphicsItem,负责碰撞检测、选中、渲染等逻辑。
  • QGraphicsView:作为“窗口”或“视口”,提供滚动、缩放、平移等功能,将 QGraphicsScene 的内容可视化。

二、基本使用示例(C++)

#include <QApplication> #include <QGraphicsView> #include <QGraphicsScene> #include <QGraphicsRectItem> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建场景 QGraphicsScene scene; scene.setSceneRect(0, 0, 800, 600); // 添加一个矩形项 QGraphicsRectItem *rect = scene.addRect(100, 100, 200, 150); rect->setBrush(Qt::red); // 创建视图并设置场景 QGraphicsView view(&scene); view.setRenderHint(QPainter::Antialiasing); // 抗锯齿 view.setWindowTitle("QGraphicsView 示例"); view.resize(800, 600); view.show(); return app.exec(); } 

三、QGraphicsView 核心功能详解

1. 视图变换(缩放、平移)

// 缩放 view.scale(1.2, 1.2); // 放大 20% view.resetTransform(); // 重置变换 // 平移(通过设置视口中心) view.centerOn(400, 300); // 将 (400,300) 居中显示 // 或者使用 scrollContentsBy / translate 
更灵活的方式:重写 wheelEvent 实现鼠标滚轮缩放:
void MyGraphicsView::wheelEvent(QWheelEvent *event) { double scaleFactor = 1.15; if (event->angleDelta().y() > 0) { scale(scaleFactor, scaleFactor); } else { scale(1.0 / scaleFactor, 1.0 / scaleFactor); } } 

2. 渲染优化

view.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿 view.setRenderHint(QPainter::SmoothPixmapTransform, true); // 平滑缩放图片 view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate); // 更新模式 

常用更新模式:

  • MinimalViewportUpdate(默认):只重绘变化区域。
  • FullViewportUpdate:整个视口重绘(适合复杂动画或透明效果)。

3. 交互控制

view.setDragMode(QGraphicsView::ScrollHandDrag); // 拖拽平移(像手抓着移动) view.setDragMode(QGraphicsView::RubberBandDrag); // 橡皮筋选择多个项 

4. 坐标系统

  • 场景坐标(Scene Coordinates):以 QGraphicsScene 为基准(通常原点在左上角)。
  • 视图坐标(View Coordinates):以 QGraphicsView 窗口为基准(像素坐标)。
  • 项坐标(Item Coordinates):每个 QGraphicsItem 自身的局部坐标。

常用转换函数:

QPointF scenePos = view.mapToScene(viewPos); // 视图 → 场景 QPoint viewPos = view.mapFromScene(scenePos); // 场景 → 视图 

5. 背景与网格(自定义绘制)

重写 drawBackground()

class MyGraphicsView : public QGraphicsView { protected: void drawBackground(QPainter *painter, const QRectF &rect) override { QGraphicsView::drawBackground(painter, rect); // 绘制网格 qreal left = int(rect.left()) - (int(rect.left()) % 20); qreal top = int(rect.top()) - (int(rect.top()) % 20); QVarLengthArray<QLineF, 100> lines; for (qreal x = left; x < rect.right(); x += 20) lines.append(QLineF(x, rect.top(), x, rect.bottom())); for (qreal y = top; y < rect.bottom(); y += 20) lines.append(QLineF(rect.left(), y, rect.right(), y)); painter->setPen(QPen(QColor(200, 200, 200), 0)); painter->drawLines(lines.data(), lines.size()); } }; 

四、性能建议

  • 避免在 paint() 中做复杂计算,应提前缓存。
  • 使用 QGraphicsItem::setCacheMode(QGraphicsItem::DeviceCoordinateCache) 提升渲染速度。
  • 对于大量静态项,考虑合并为一个 QGraphicsItem(如用 QPicture)。

启用 OpenGL(可选):

view.setViewport(new QOpenGLWidget); 

五、常见应用场景

  • 流程图/拓扑图编辑器
  • 2D 地图/平面图展示
  • 可视化建模工具(如 UML、电路图)
  • 游戏地图编辑器

六、参考资料


如果你有具体需求(比如实现拖拽、自定义 item、多视图同步等),可以告诉我,我可以给出针对性代码示例。

4.QGraphicsItem

QGraphicsItem 是 Qt 框架中用于 2D 图形场景(QGraphicsScene)中的基本图形项类,是所有可放置在 QGraphicsScene 中的图形对象的基类。它是 Qt Graphics View Framework 的核心组成部分之一。


一、概述

Qt 的 Graphics View Framework 由三部分组成:

  1. View(视图)QGraphicsView —— 用于显示场景。
  2. Scene(场景)Q/GraphicsScene —— 容纳并管理图形项。
  3. Item(图形项)QGraphicsItem 及其子类 —— 实际绘制的内容。

QGraphicsItem 本身是一个抽象基类,通常需要继承它来自定义图形项,或者直接使用 Qt 提供的内置子类,如:

  • QGraphicsRectItem
  • QGraphicsEllipseItem
  • QGraphicsLineItem
  • QGraphicsPixmapItem
  • QGraphicsTextItem
  • QGraphicsPathItem

二、核心功能

1. 坐标系统

  • 本地坐标(Local Coordinates):每个 QGraphicsItem 都有自己的坐标系,原点 (0,0) 通常是其“中心”或左上角(取决于实现)。
  • 场景坐标(Scene Coordinates):所有项在 QGraphicsScene 中的位置。
  • 视图坐标(View Coordinates):对应于屏幕像素。

可通过以下函数转换坐标:

QPointF mapToScene(const QPointF &point) const; QPointF mapFromScene(const QPointF &point) const; QPointF mapToParent(const QPointF &point) const; QPointF mapFromParent(const QPointF &point) const; 

2. 位置与变换

  • setPos(x, y) / pos():设置/获取在父项或场景中的位置。
  • 支持旋转(setRotation())、缩放(setScale())、剪切等仿射变换。
  • 变换基于 QTransform,通过 setTransform() 可自定义。

3. 绘制(Painting)

必须重写以下纯虚函数(如果自定义项):

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; 

同时需实现:

QRectF boundingRect() const override; 
⚠️ 注意:boundingRect() 必须返回该项在本地坐标系中包围盒(包括所有可能绘制内容),用于裁剪和碰撞检测。

可选重写:

QPainterPath shape() const; // 更精确的点击/碰撞区域,默认返回 boundingRect 的路径 

4. 交互与事件

QGraphicsItem 支持鼠标、键盘、拖拽等事件,例如:

void mousePressEvent(QGraphicsSceneMouseEvent *event) override; void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; 

要启用 hover 事件,需设置:

setAcceptHoverEvents(true); 

要接收键盘事件,需:

setFlag(QGraphicsItem::ItemIsFocusable, true); 

5. 父子关系与 Z 顺序

  • 项可以有父子关系:子项随父项移动、旋转。
  • 使用 setZValue() 控制绘制顺序(值越大越靠前)。
  • 默认情况下,添加顺序决定 Z 顺序,但可手动调整。

6. 碰撞检测

  • collidesWithItem() / collidesWithPath()
  • 基于 shape() 路径进行精确检测(比 boundingRect() 更准)

三、常用标志(Flags)

通过 setFlag() 设置行为:

setFlag(QGraphicsItem::ItemIsMovable); // 可拖动 setFlag(QGraphicsItem::ItemIsSelectable); // 可被选中 setFlag(QGraphicsItem::ItemIsFocusable); // 可获得焦点 setFlag(QGraphicsItem::ItemClipsToShape); // 裁剪到 shape() setFlag(QGraphicsItem::ItemSendsGeometryChanges); // 位置/变换改变时触发 itemChange 

四、自定义 QGraphicsItem 示例

// myitem.h #ifndef MYITEM_H #define MYITEM_H #include <QGraphicsItem> #include <QPainter> class MyItem : public QGraphicsItem { public: MyItem(); QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override; }; #endif // MYITEM_H 
// myitem.cpp #include "myitem.h" #include <QGraphicsSceneMouseEvent> #include <QCursor> MyItem::MyItem() { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); setAcceptHoverEvents(true); } QRectF MyItem::boundingRect() const { return QRectF(-20, -20, 40, 40); // 以 (0,0) 为中心的正方形 } void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); painter->setPen(Qt::black); if (option->state & QStyle::State_Selected) painter->setBrush(Qt::red); else painter->setBrush(Qt::blue); painter->drawRect(boundingRect()); } void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) qDebug() << "Item clicked at:" << event->pos(); QGraphicsItem::mousePressEvent(event); } 

使用方式:

QGraphicsScene scene; MyItem *item = new MyItem(); scene.addItem(item); item->setPos(100, 100); QGraphicsView view(&scene); view.show(); 

五、性能优化建议

  • 尽量缩小 boundingRect() 范围。
  • 对复杂图形,使用 QGraphicsItemGroup 或缓存(setCacheMode(DeviceCoordinateCache))。
  • 避免在 paint() 中做耗时操作。
  • 使用 prepareGeometryChange() 在修改几何前通知场景。

六、常见子类速查

类名用途
QGraphicsRectItem矩形
QGraphicsEllipseItem椭圆/圆
QGraphicsLineItem直线
QGraphicsPixmapItem图像
QGraphicsTextItem文本
QGraphicsPathItem自定义路径
QGraphicsPolygonItem多边形

七、参考资料

  • Qt 官方文档 - QGraphicsItem
  • 《C++ GUI Programming with Qt 6》第 8 章
  • Qt Examples: graphicsview/ 目录下的示例(如 elasticnodes, diagramscene

如果你有具体需求(比如实现可拖拽连线、自定义动画项、与 OpenGL 结合等),可以继续提问!

5.QGraphicsRectItem

QGraphicsRectItem 是 Qt 框架中用于在 QGraphicsScene 中表示矩形图元(graphics item)的一个类。它是 QGraphicsItem 的子类,专门用于绘制矩形、正方形或带圆角的矩形。


一、基本介绍

  • 头文件#include <QGraphicsRectItem>
  • 继承关系QGraphicsRectItemQAbstractGraphicsShapeItemQGraphicsItem
  • 功能:提供一个可自定义位置、大小、颜色、边框等属性的矩形图元,常用于图形编辑器、流程图、UI 设计工具等场景。

二、构造函数

// 默认构造,矩形为 (0, 0, 0, 0) QGraphicsRectItem(QGraphicsItem *parent = nullptr); // 指定矩形区域(x, y, width, height) QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr); // 使用 QRectF 构造 QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = nullptr); 
注意:xy 是相对于图元自身坐标系的左上角位置(即局部坐标),不是场景坐标。

三、常用成员函数

1. 设置/获取矩形区域

void setRect(const QRectF &rect); void setRect(qreal x, qreal y, qreal width, qreal height); QRectF rect() const; 

2. 绘图相关(继承自 QAbstractGraphicsShapeItem)

void setPen(const QPen &pen); // 设置边框样式 void setBrush(const QBrush &brush); // 设置填充样式 QPen pen() const; QBrush brush() const; 

3. 其他通用属性(继承自 QGraphicsItem)

void setPos(qreal x, qreal y); // 设置在场景中的位置 void setFlag(GraphicsItemFlag flag, bool enabled = true); // 启用交互(如可选、可移动等) void setZValue(qreal z); // 设置 Z 轴层级(控制重叠顺序) 

四、示例代码

#include <QApplication> #include <QGraphicsView> #include <QGraphicsScene> #include <QGraphicsRectItem> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建场景 QGraphicsScene scene; scene.setSceneRect(-200, -200, 400, 400); // 创建矩形图元 QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 50); rect->setPen(QPen(Qt::black, 2)); rect->setBrush(QBrush(Qt::yellow)); // 启用交互 rect->setFlag(QGraphicsItem::ItemIsSelectable); rect->setFlag(QGraphicsItem::ItemIsMovable); // 添加到场景 scene.addItem(rect); // 创建视图并显示 QGraphicsView view(&scene); view.setRenderHint(QPainter::Antialiasing); view.setWindowTitle("QGraphicsRectItem 示例"); view.resize(500, 500); view.show(); return app.exec(); } 

五、注意事项

  1. 坐标系统
    • rect() 定义的是图元的本地坐标
    • setPos() 设置的是图元在场景中的位置
  2. 性能
    • 对于大量静态矩形,考虑使用 QGraphicsItemGroup 或自定义 QGraphicsItem 以提升性能。
  3. 信号与槽
    • QGraphicsRectItem 本身不发射信号。若需响应点击、移动等事件,可:
      • 重写 mousePressEvent 等虚函数(需继承并自定义类);
      • 或通过 QGraphicsScene 的信号(如 selectionChanged())间接处理。

若你希望矩形中心位于 (100, 100),可以:

rect->setRect(-50, -25, 100, 50); // 以中心为原点 rect->setPos(100, 100); 

六、扩展用法

  • 圆角矩形QGraphicsRectItem 本身不支持圆角。如需圆角,应使用 QGraphicsPathItem + QPainterPath::addRoundedRect()
  • 动画:配合 QPropertyAnimation 可对 posrect 等属性做动画(需注册元对象系统属性)。

七、相关类

类名说明
QGraphicsEllipseItem椭圆/圆形图元
QGraphicsLineItem直线图元
QGraphicsTextItem文本图元
QGraphicsPathItem任意路径图元(更灵活)

如需进一步实现交互逻辑(如拖拽改变大小),通常需要继承 QGraphicsRectItem 并重写鼠标事件处理函数。

如果你有具体需求(比如“如何让矩形可调整大小”或“如何响应点击事件”),欢迎继续提问!

6.QQuickWindow

QQuickWindow 是 Qt Quick 模块中的一个关键类,用于显示基于 QML(Qt Meta-Object Language)构建的用户界面。它是 QWindow 的子类,专为渲染 Qt Quick 内容而设计。


基本介绍

  • 头文件#include <QQuickWindow>
  • 继承关系QQuickWindowQWindowQObject
  • 所属模块QtQuick

QQuickWindow 提供了一个窗口,可以加载并显示一个 QQuickItem(通常是 QQuickView 的根项或直接设置的 contentItem)。它负责管理场景图(Scene Graph)的渲染、事件处理、动画调度等。


常见用法

1. 创建 QQuickWindow 并加载 QML
#include <QGuiApplication> #include <QQuickWindow> #include <QQmlEngine> #include <QQmlComponent> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickWindow window; QQmlEngine engine; QQmlComponent component(&engine, QUrl("qrc:/main.qml")); QObject *obj = component.create(); if (auto item = qobject_cast<QQuickItem*>(obj)) { window.setContentItem(item); } window.show(); return app.exec(); } 
注意:通常更常见的是使用 QQuickView(继承自 QQuickWindow),它封装了加载 QML 文件的逻辑。
2. 使用 QQuickView(推荐方式)
#include <QGuiApplication> #include <QQuickView> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView view; view.setSource(QUrl("qrc:/main.qml")); view.show(); return app.exec(); } 

核心特性

  • Scene Graph 渲染QQuickWindow 使用高效的场景图系统进行 GPU 加速渲染。
  • 事件处理:支持鼠标、键盘、触摸、拖拽等事件,并将它们传递给 QML 中的对象。
  • 多线程渲染:默认启用渲染线程(可配置),提升 UI 流畅度。
  • 透明窗口支持:可通过 setFormat()setColor(Qt::transparent) 实现透明背景。
  • 帧同步与动画:集成 Qt 的动画系统,每帧自动更新。

常用方法

方法说明
setContentItem(QQuickItem *item)设置窗口显示的根 QML 项
contentItem()获取当前内容项
setPersistentSceneGraph(bool)控制场景图是否在隐藏时保留
scheduleRenderJob(...)调度自定义渲染任务
resetOpenGLState()在混合 OpenGL 渲染时重置状态

注意事项

  • QQuickWindow 本身不自动加载 QML 文件,需手动创建 QQmlComponent 或使用 QQuickView
  • 若需与 QWidget 混合使用,应考虑 QWidget::createWindowContainer() 包装 QQuickWindow
  • 在嵌入式或无窗口系统(如 EGLFS)中,QQuickWindow 是主要的 UI 显示载体。

如果你有具体问题,比如:

  • 如何在 C++ 中与 QML 交互?
  • 如何自定义渲染?
  • 如何处理窗口透明或全屏?
  • 性能优化建议?

欢迎继续提问!

7.QSGNode

QSGNode 是 Qt Quick Scene Graph(场景图)系统中的一个核心类,用于表示场景图中的节点。Qt Quick 使用场景图(Scene Graph)作为其底层渲染架构,以高效地渲染用户界面。QSGNode 是所有场景图节点的基类。


基本概念

  • 场景图(Scene Graph):一种树状结构,用于描述 UI 的视觉内容。每个节点代表屏幕上的一个可视元素或一组操作(如变换、裁剪等)。
  • QSGNode:抽象基类,不直接实例化,而是通过其子类(如 QSGGeometryNodeQSGTransformNodeQSGClipNode 等)来构建具体的渲染内容。

主要子类

子类用途
QSGGeometryNode表示具有几何形状和材质(着色器/纹理)的可渲染对象,常用于自定义绘制。
QSGTransformNode应用仿射变换(如平移、旋转、缩放)到其子节点。
QSGClipNode定义裁剪区域,限制子节点的绘制范围。
QSGRootNode场景图的根节点。
QSGOpacityNode控制子树的透明度。

典型使用场景

  1. 性能优化
    场景图在渲染线程中运行,与 UI 线程分离。正确使用 QSGNode 可以避免不必要的重建,提升性能。

自定义 QQuickItem 渲染
当你继承 QQQickItem 并重写 updatePaintNode() 方法时,需要返回一个 QSGNode*(通常是 QSGGeometryNode),用于描述如何渲染该 Item。

QSGNode *MyItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { QSGGeometryNode *node = static_cast<QSGGeometryNode *>(oldNode); if (!node) { node = new QSGGeometryNode; // 设置 geometry 和 material } // 更新 geometry 或 transform return node; } 

注意事项

  • 线程安全QSGNode 及其子类通常在渲染线程中访问,因此在 UI 线程中修改节点时需谨慎(通常通过 updatePaintNode 安全地同步)。
  • 内存管理:Qt Quick 负责管理场景图节点的生命周期,一般不需要手动 delete。
  • 不要跨帧复用未更新的节点:若内容未变,可返回旧节点以提升效率;若内容变化,必须更新节点数据。

如果你有具体问题,比如如何创建自定义几何体、如何使用 TransformNode,或者遇到性能问题,欢迎继续提问!

8.QQuickItem

QQuickItem 是 Qt Quick 模块中的一个核心类,用于表示 Qt Quick 场景图(Scene Graph)中的可视项(visual item)。它是所有可视 QML 元素(如 RectangleImageText 等)在 C++ 层的基类。


基本信息

  • 头文件#include <QQuickItem>
  • 继承自QObject
  • 派生类QQuickPaintedItemQQuickFramebufferObject、自定义 QML 类型等
  • 模块Qt Quick

主要功能

  1. 可视元素的基础
    所有在 QML 中可见的元素(除了非可视元素如 TimerBehavior)都对应一个 QQuickItem 实例。
  2. 坐标系统与变换
    • 提供 x, y, width, height 等属性。
    • 支持旋转(rotation)、缩放(scale)、变换原点(transformOrigin)等。
    • 支持父子坐标转换(mapToItem(), mapFromItem())。
  3. 事件处理
    可重写以下虚函数以响应用户交互:
    • mousePressEvent(QMouseEvent *)
    • mouseMoveEvent(QMouseEvent *)
    • touchEvent(QTouchEvent *)
    • hoverEnterEvent(QHoverEvent *)
    • keyPressEvent(QKeyEvent *)(需先设置 focus: true
  4. 绘制支持
    • 默认不直接绘制内容(由场景图自动处理)。
    • 若需自定义绘制,可继承 QQuickPaintedItem 并重写 paint() 方法(使用 QPainter)。
    • 更高性能的方式是直接操作场景图(通过 updatePaintNode()),但这更复杂。
  5. 与 QML 交互
    • 可通过 qmlRegisterType() 将 C++ 类注册为 QML 类型。
    • 使用 Q_PROPERTY 暴露属性到 QML。
    • 使用 Q_INVOKABLEQ_SLOT 暴露方法。

示例:自定义 QQuickItem(使用 QQuickPaintedItem)

// myitem.h #include <QQuickPaintedItem> #include <QColor> class MyItem : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) public: MyItem(QQuickItem *parent = nullptr) : QQuickPaintedItem(parent) {} void paint(QPainter *painter) override { painter->fillRect(boundingRect(), m_color); } QColor color() const { return m_color; } void setColor(const QColor &c) { if (m_color != c) { m_color = c; emit colorChanged(); update(); // 触发重绘 } } signals: void colorChanged(); private: QColor m_color = Qt::red; }; 

在 main.cpp 中注册:

qmlRegisterType<MyItem>("MyModule", 1, 0, "MyItem"); 

在 QML 中使用:

import MyModule 1.0 MyItem { width: 100 height: 100 color: "blue" } 

注意事项

  • 线程安全QQuickItem 的大多数方法应在 GUI 线程中调用。
  • 性能:频繁调用 update() 或在 paint() 中做复杂计算会影响性能。
  • 父子关系QQuickItem 支持父子结构,子项的坐标相对于父项。

如果你有具体问题(比如如何处理鼠标事件、如何集成 OpenGL 内容、如何优化绘制性能等),欢迎继续提问!

8.Qt Quick 3D

Qt Quick 3D 是 Qt 框架中的一个模块,用于在 Qt Quick 应用程序中创建和渲染 3D 内容。它将 3D 图形与 Qt Quick 的声明式 UI 编程模型无缝集成,使开发者能够使用 QML(Qt Meta-Object Language)轻松构建具有 3D 元素的现代用户界面。


核心特性

  1. 基于 Qt Quick 的 3D 渲染
    • 使用熟悉的 QML 语法定义 3D 场景。
    • 支持与 2D Qt Quick 元素混合(例如叠加按钮、文本等)。
  2. 基于物理的渲染(PBR)
    • 支持金属度/粗糙度工作流。
    • 提供逼真的材质和光照效果。
  3. 内置 3D 资源支持
    • 可导入 .mesh(Qt 自定义格式)、.gltf / .glb(推荐)、.obj 等模型。
    • 支持纹理、法线贴图、环境光遮蔽等。
  4. 动画与交互
    • 通过 PropertyAnimationNumberAnimation 等对 3D 对象属性(如位置、旋转)进行动画。
    • 支持鼠标/触摸交互(如旋转、缩放模型)。
  5. 自定义着色器(可选)
    • 支持使用 Effect、ShaderEffect 等编写自定义 GLSL 着着色器。
  6. 跨平台
    • 支持 Windows、macOS、Linux、Android、iOS 等,依赖 OpenGL ES 或 Vulkan(取决于平台)。

基本 QML 示例

import QtQuick import QtQuick.Window import QtQuick3D Window { width: 800 height: 600 visible: true title: "Qt Quick 3D 示例" View3D { anchors.fill: parent camera: camera PerspectiveCamera { id: camera position: Qt.vector3d(0, 0, 600) } DirectionalLight { position: Qt.vector3d(500, 500, 500) color: "#ffffff" brightness: 1.0 } Model { source: "#Cube" // 内置立方体 position: Qt.vector3d(0, 0, 0) scale: Qt.vector3d(200, 200, 200) materials: DefaultMaterial { diffuseColor: "steelblue" } } } } 

常用组件

组件说明
View3D3D 渲染视口
PerspectiveCamera / OrthographicCamera相机类型
Model表示 3D 模型(可加载外部文件或使用内置形状)
DefaultMaterial / PrincipledMaterial材质系统(后者支持完整 PBR)
DirectionalLight / PointLight / SpotLight光源类型

导入外部模型(如 glTF)

Model { source: "models/car.glb" materials: PrincipledMaterial { baseColor: "red" metalness: 0.8 roughness: 0.2 } } 
注意:需确保模型路径正确,并在 .pro 文件中包含资源(若打包进应用)。

性能提示

  • 避免每帧更新复杂几何体。
  • 使用实例化(InstanceList)渲染大量相同对象。
  • 合理设置 View3DrenderMode(如 Overlay vs Underlay)。

学习资源

  • Qt 官方文档 - Qt Quick 3D
  • Qt Creator 内置的 3D Examples(如 simple3d, dynamicmaterials, instancing
  • Qt Design Studio(可视化设计 3D 场景)

如果你有具体问题(如“如何实现模型点击检测?”、“如何动态加载 glTF?”、“性能优化技巧?”),欢迎继续提问!

Read more

C++ 设计模式概述及常用模式

C++ 设计模式概述 本文介绍了C++中23种设计模式的分类及实现示例,主要分为三大类: 创建型模式(5个):单例模式(常用)、工厂方法模式(常用)、抽象工厂模式(常用)、建造者模式和原型模式。这些模式专注于对象的创建机制。 结构型模式(7个):适配器模式(常用)、桥接模式、组合模式和装饰器模式(常用)等。这些模式处理类和对象的组合方式。 行为型模式:未完整列出,但包含观察者模式等(未展示完整代码)。 文章通过简洁的C++代码示例展示了常用设计模式的实现方法,如单例模式通过私有构造函数和静态方法确保唯一实例,工厂方法模式通过抽象工厂类创建产品等。这些模式为解决特定设计问题提供了可重用的解决方案。 C++ 设计模式概述及常用模式 设计模式可分为三大类:创建型、结构型、行为型。以下是23个设计模式的分类及代码示例: 一、创建型模式(5个) 1. 单例模式(Singleton)⭐ 常用 classSingleton{private:static

By Ne0inhk
手把手实现 STL Set/Map:从零编写一棵红黑树到完整容器封装

手把手实现 STL Set/Map:从零编写一棵红黑树到完整容器封装

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 架构与实现:总览设计框架,深入源码细节 * 二. 核心设计思路:红黑树的泛型复用 * 2.1 红黑树的模板参数设计 * 2.2 仿函数 KeyOfT:统一 key 提取逻辑 * 2.3 核心约束:key 不可修改 * 三. 基础组件实现:红黑树与仿函数 * 3.1 红黑树节点结构 * 3.2 仿函数实现(map/set 层) * 3.2.1

By Ne0inhk
Re:从零开始的 C++ STL篇(七)二叉搜索树增删查操作系统讲解(含代码)+key/key-value场景联合分析

Re:从零开始的 C++ STL篇(七)二叉搜索树增删查操作系统讲解(含代码)+key/key-value场景联合分析

◆ 博主名称: 晓此方-ZEEKLOG博客大家好,欢迎来到晓此方的博客。⭐️C++系列个人专栏: 主题曲:C++程序设计⭐️ 踏破千山志未空,拨开云雾见晴虹。 人生何必叹萧瑟,心在凌霄第一峰 0.1概要&序論 这里是「此方」,好久不见。 今天我们要学习的是二叉搜索树。它是在普通二叉树的基础上加入特定约束,从而具备了高效的搜索能力。虽然这种结构能够支持高效的插入、删除与查找操作,但其性能背后也隐藏着潜在的 效率风险 。同时,在 key 与 key-value 两种不同的应用场景 下,二叉搜索树的设计与实现方式也会产生不同的变化。这里是「此方」。让我们现在开始吧! 前情提要,没有系统学习过一般二叉树的小伙伴直接看这篇文章可能会有些吃力,此方在这里留一个传送门:Re:从零开始的链式二叉树:建树、遍历、计数、查找、判全、销毁全链路实现与底层剖析 一,二叉搜索树的概念

By Ne0inhk