这个框架是一个相对成熟的渲染引擎的上层框架,通常也可以会叫做 Scene - View。
在QT中,GraphicsView是一个与QWdiget系列一点点不一样的系统。这个系统主要由下面几个框架类构成:QGraphicsView, QGraphicsScene, QGraphicsItem
QGrahpicsView是从原生的QWidget继承过来,QGraphics-View系统中,他承担的也是视口的指责,Viewport,Viewport相当于显示设备的一个矩形区域。
QGraphicsScene 是一个管理器,用来管理所有的QGraphicsItem,包括根据坐标查询Item,排序Item,绘制Item等。
QGraphicsItem 是所有可见的元件。一个完整的UI界面,由各种QGraphicsItem组合起来。这些QGraphicsItem之间由一棵多叉树组织。
要架构一个基于GraphicsView的UI库,需要做如下的三件事情:
- 我们需要先由一个 QGraphicsView, 这个是UI显示的地方,也就是装满可见原色的Scene,
- 然后需要一个QGraphicsScene 用来管理所有可见的界面元素,
- 要实现UI功能,我们需要用各种从QGraphicsItem拼装成UI控件,并赋予他控件的逻辑。
对应到Duifw,我们的DuiFrameWindow 就是从 QGraphicsView 继承过来的,也就是说它是一个独立的视口,相当于操作系统的一个窗口.
在DuiFrameWindow 中 void DuiFrameWindow::_initScene(), 函数中,我们为每一个 DuiFrameWindow 创建了一个标准的 QGraphicsScene, 并且在 scene 上我们 add 了一个 DuiRootItem,然后我们就在 rootitem上构建我们的所有UI控件, 从 DuiRootItem: m_rootItem 上 我们add 三个子Item ,分别是 DuiBackgroundItem:m_backgroundItem, DuiTitlebar:m_titlebar, DuiSpacerItem:m_contentItem, 然后我们定义了一个rootWidget() 函数 用来返回 DuiSpacerItem:m_contentItem, 后面通过xml文件配置的一个窗口,就通过访问rootWidget(), 把所有DuiFrameWindow的孩子节点都以 这个rootWidget为 父节点,如下代码:
createChild(child->child(index), frame->rootWidget());
这样就构建了一个QGraphicsItem的多叉树。前面有一个细节,没有列出,就是我们的DuiWidget, 是一个什么, 我们的DuiWidget是从QGraphicsWidget,继承而来的,也就是说它本身是一个符合 QGraphicsScene - QGraphicsItem体系的可视元件。
了解了的GraphicsView的构成框架后,对于QGraphicsItem的消息来源,以及这个框架中的消息走向能够大概有了猜测了。
QGraphicsView 会把 原来的QWidget中的各种QHoverEvent, QInputEvent,......等等一些列命令,转换成各种 QGraphicsSceneEvent ,QGraphicsSceneMouseEvent,QGraphicsSceneWheelEvent......,,,然后传递给当前View绑定的QGraphicsScene。然后通过Scene传递给 QGraphicsitem,QGraphicsScene 有如下的一堆消息处理接口:
通过上述的分发,最后消息会通过下面的接口传递到具体的item,所有的scene消息都是走接口:
这样就完成了从windows消息到 QGraphicsItem 的消息处理的流程。
到此。QGraphics - View 框架就简述完成了。