這個框架是一個相對成熟的渲染引擎的上層框架,通常也可以會叫做 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 框架就簡述完成了。