qt c++ 场景图架构的类都有什么
1.qt c++ 场景图架构的类都有什么
在Qt的C++场景图架构中,不同模块(如Qt Widgets、Qt Quick、Qt 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:功能模块(如
QCamera、QMesh、QMaterial、QTransform),附加到实体上定义其行为。 - 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 提供的标准项(如
QGraphicsRectItem、QGraphicsEllipseItem),也可以是自定义子类。
三者关系:
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. 动画支持
配合 QPropertyAnimation 或 QGraphicsItemAnimation(旧版)实现动画。
2. 拖放(Drag & Drop)
重写 dragEnterEvent、dropEvent 等方法支持拖放操作。
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(),场景矩形是否包含该项 |
| 无法交互 | 确保设置了 ItemIsMovable、ItemIsSelectable 等标志 |
| 坐标混乱 | 理解局部坐标 vs 场景坐标,善用 mapToScene() |
| 性能差 | 启用缓存、减少重绘、使用 BSP 索引 |
八、参考文档
- Qt 官方文档 - QGraphicsScene
- 《C++ GUI Programming with Qt 6》第 12 章(Graphics View)
如需进一步了解自定义图形项、动画、拖拽、缩放/平移控制等内容,可继续提问!
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、电路图)
- 游戏地图编辑器
六、参考资料
- Qt 官方文档 - Graphics View Framework
- 《C++ GUI Programming with Qt 6》第 13 章
如果你有具体需求(比如实现拖拽、自定义 item、多视图同步等),可以告诉我,我可以给出针对性代码示例。
4.QGraphicsItem
QGraphicsItem 是 Qt 框架中用于 2D 图形场景(QGraphicsScene)中的基本图形项类,是所有可放置在 QGraphicsScene 中的图形对象的基类。它是 Qt Graphics View Framework 的核心组成部分之一。
一、概述
Qt 的 Graphics View Framework 由三部分组成:
- View(视图):
QGraphicsView—— 用于显示场景。 - Scene(场景):
Q/GraphicsScene—— 容纳并管理图形项。 - Item(图形项):
QGraphicsItem及其子类 —— 实际绘制的内容。
QGraphicsItem 本身是一个抽象基类,通常需要继承它来自定义图形项,或者直接使用 Qt 提供的内置子类,如:
QGraphicsRectItemQGraphicsEllipseItemQGraphicsLineItemQGraphicsPixmapItemQGraphicsTextItemQGraphicsPathItem
二、核心功能
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> - 继承关系:
QGraphicsRectItem←QAbstractGraphicsShapeItem←QGraphicsItem - 功能:提供一个可自定义位置、大小、颜色、边框等属性的矩形图元,常用于图形编辑器、流程图、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); 注意:x和y是相对于图元自身坐标系的左上角位置(即局部坐标),不是场景坐标。
三、常用成员函数
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(); } 五、注意事项
- 坐标系统:
rect()定义的是图元的本地坐标。setPos()设置的是图元在场景中的位置。
- 性能:
- 对于大量静态矩形,考虑使用
QGraphicsItemGroup或自定义QGraphicsItem以提升性能。
- 对于大量静态矩形,考虑使用
- 信号与槽:
QGraphicsRectItem本身不发射信号。若需响应点击、移动等事件,可:- 重写
mousePressEvent等虚函数(需继承并自定义类); - 或通过
QGraphicsScene的信号(如selectionChanged())间接处理。
- 重写
若你希望矩形中心位于 (100, 100),可以:
rect->setRect(-50, -25, 100, 50); // 以中心为原点 rect->setPos(100, 100); 六、扩展用法
- 圆角矩形:
QGraphicsRectItem本身不支持圆角。如需圆角,应使用QGraphicsPathItem+QPainterPath::addRoundedRect()。 - 动画:配合
QPropertyAnimation可对pos、rect等属性做动画(需注册元对象系统属性)。
七、相关类
| 类名 | 说明 |
|---|---|
QGraphicsEllipseItem | 椭圆/圆形图元 |
QGraphicsLineItem | 直线图元 |
QGraphicsTextItem | 文本图元 |
QGraphicsPathItem | 任意路径图元(更灵活) |
如需进一步实现交互逻辑(如拖拽改变大小),通常需要继承 QGraphicsRectItem 并重写鼠标事件处理函数。
如果你有具体需求(比如“如何让矩形可调整大小”或“如何响应点击事件”),欢迎继续提问!
6.QQuickWindow
QQuickWindow 是 Qt Quick 模块中的一个关键类,用于显示基于 QML(Qt Meta-Object Language)构建的用户界面。它是 QWindow 的子类,专为渲染 Qt Quick 内容而设计。
基本介绍
- 头文件:
#include <QQuickWindow> - 继承关系:
QQuickWindow←QWindow←QObject - 所属模块:
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:抽象基类,不直接实例化,而是通过其子类(如
QSGGeometryNode、QSGTransformNode、QSGClipNode等)来构建具体的渲染内容。
主要子类
| 子类 | 用途 |
|---|---|
QSGGeometryNode | 表示具有几何形状和材质(着色器/纹理)的可渲染对象,常用于自定义绘制。 |
QSGTransformNode | 应用仿射变换(如平移、旋转、缩放)到其子节点。 |
QSGClipNode | 定义裁剪区域,限制子节点的绘制范围。 |
QSGRootNode | 场景图的根节点。 |
QSGOpacityNode | 控制子树的透明度。 |
典型使用场景
- 性能优化
场景图在渲染线程中运行,与 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 元素(如 Rectangle、Image、Text 等)在 C++ 层的基类。
基本信息
- 头文件:
#include <QQuickItem> - 继承自:
QObject - 派生类:
QQuickPaintedItem、QQuickFramebufferObject、自定义 QML 类型等 - 模块:
Qt Quick
主要功能
- 可视元素的基础
所有在 QML 中可见的元素(除了非可视元素如Timer、Behavior)都对应一个QQuickItem实例。 - 坐标系统与变换
- 提供
x,y,width,height等属性。 - 支持旋转(
rotation)、缩放(scale)、变换原点(transformOrigin)等。 - 支持父子坐标转换(
mapToItem(),mapFromItem())。
- 提供
- 事件处理
可重写以下虚函数以响应用户交互:mousePressEvent(QMouseEvent *)mouseMoveEvent(QMouseEvent *)touchEvent(QTouchEvent *)hoverEnterEvent(QHoverEvent *)keyPressEvent(QKeyEvent *)(需先设置focus: true)
- 绘制支持
- 默认不直接绘制内容(由场景图自动处理)。
- 若需自定义绘制,可继承
QQuickPaintedItem并重写paint()方法(使用 QPainter)。 - 更高性能的方式是直接操作场景图(通过
updatePaintNode()),但这更复杂。
- 与 QML 交互
- 可通过
qmlRegisterType()将 C++ 类注册为 QML 类型。 - 使用
Q_PROPERTY暴露属性到 QML。 - 使用
Q_INVOKABLE或Q_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 元素的现代用户界面。
核心特性
- 基于 Qt Quick 的 3D 渲染
- 使用熟悉的 QML 语法定义 3D 场景。
- 支持与 2D Qt Quick 元素混合(例如叠加按钮、文本等)。
- 基于物理的渲染(PBR)
- 支持金属度/粗糙度工作流。
- 提供逼真的材质和光照效果。
- 内置 3D 资源支持
- 可导入
.mesh(Qt 自定义格式)、.gltf/.glb(推荐)、.obj等模型。 - 支持纹理、法线贴图、环境光遮蔽等。
- 可导入
- 动画与交互
- 通过
PropertyAnimation、NumberAnimation等对 3D 对象属性(如位置、旋转)进行动画。 - 支持鼠标/触摸交互(如旋转、缩放模型)。
- 通过
- 自定义着色器(可选)
- 支持使用 Effect、ShaderEffect 等编写自定义 GLSL 着着色器。
- 跨平台
- 支持 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" } } } } 常用组件
| 组件 | 说明 |
|---|---|
View3D | 3D 渲染视口 |
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)渲染大量相同对象。 - 合理设置
View3D的renderMode(如OverlayvsUnderlay)。
学习资源
- Qt 官方文档 - Qt Quick 3D
- Qt Creator 内置的 3D Examples(如
simple3d,dynamicmaterials,instancing) - Qt Design Studio(可视化设计 3D 场景)
如果你有具体问题(如“如何实现模型点击检测?”、“如何动态加载 glTF?”、“性能优化技巧?”),欢迎继续提问!