MCV模型
有時,我們的系統需要顯示大量資料,比如從資料庫中讀取資料,以自己的方式顯示在自己的應用程式的介面中。早期的 Qt 要實現這個功能,需要定義一個元件,在這個元件中儲存一個資料物件,比如一個列表。我們對這個列表進行查詢、插入等的操作,或者把修改的地方寫回,然後重新整理元件進行顯示。這個思路很簡單,也很清晰,但是對於大型程式,這種設計就顯得蒼白無力。比如,在一個大型系統中,你的資料可能很大,全部存入一個元件的資料物件中,效率會很低,並且這樣的設計也很難在不同元件之間共享資料。如果你要幾個元件共享一個資料物件,要麼你就要用存取函式公開這個資料物件,要麼你就必須把這個資料物件放進不同的元件分別進行維護。
Smalltalk 語言發明了一種嶄新的實現,用來解決這個問題,這就是著名的 MVC 模型。對這個模型無需多言。MVC 是 Model-View-Controller 的簡寫,即模型-檢視-控制器。在 MVC 中,模型負責獲取需要顯示的資料,並且儲存這些資料的修改。每種資料型別都有它自己對應的模型,但是這些模型提供一個相同的 API,用於隱藏內部實現。檢視用於將模型資料顯示給使用者。對於數量很大的資料,或許只顯示一小部分,這樣就能很好的提高效能。控制器是模型和檢視之間的媒介,將使用者的動作解析成對資料的操作,比如查詢資料或者修改資料,然後轉發給模型執行,最後再將模型中需要被顯示的資料直接轉發給檢視進行顯示。MVC 的核心思想是分層,不同的層應用不同的功能。
Qt 4 開始,引入了類似的 model/view 架構來處理資料和麵向終端使用者的顯示之間的關係。當 MVC 的 V 和 C 結合在一起,我們就得到了 model/view 架構。這種架構依然將資料和介面分離,但是框架更為簡單。同樣,這種架構也允許使用不同介面顯示同一資料,也能夠在不改變資料的情況下新增新的顯示介面。為了處理使用者輸入,我們還引入了委託(delegate)。引入委託的好處是,我們能夠自定義資料項的渲染和編輯。
如上圖所示,模型與資料來源進行互動,為框架中其它元件提供介面。這種互動的本質在於資料來源的型別以及模型的實現方式。檢視從模型獲取模型索引,這種索引就是資料項的引用。通過將這個模型索引反向傳給模型,檢視又可以從資料來源獲取資料。在標準檢視中,委託渲染資料項;在需要編輯資料時,委託使用直接模型索引直接與模型進行互動。
總的來說,model/view 架構將傳統的 MV 模型分為三部分:模型、檢視和委託。每一個元件都由一個抽象類定義,這個抽象類提供了基本的公共介面以及一些預設實現。模型、檢視和委託則使用訊號槽進行互動:
- 來自模型的訊號通知檢視,其底層維護的資料發生了改變;
- 來自檢視的訊號提供了有關使用者與介面進行互動的資訊;
- 來自委託的訊號在使用者編輯資料項時使用,用於告知模型和檢視編輯器的狀態。
所有的模型都是QAbstractItemModel
的子類。這個類定義了供檢視和委託訪問資料的介面。模型並不儲存資料本身。這意味著,你可以將資料儲存在一個資料結構中、另外的類中、檔案中、資料庫中,或者其他你所能想到的東西中。我們將在後面再詳細討論這些內容。
QAbstractItemModel
提供的介面足夠靈活,足以應付以表格、列表和樹的形式顯示的資料。但是,如果你需要為列表或者表格設計另外的模型,直接繼承QAbstractListModel
和QAbstractTableModel
類可能更好一些,因為這兩個類已經實現了很多通用函式。關於這部分內容,我們也會在後文中詳述。
Qt 內建了許多標準模型:
-
QStringListModel
:儲存簡單的字串列表。 -
QStandardItemModel
:可以用於樹結構的儲存,提供了層次資料。 -
QFileSystemModel
:本地系統的檔案和目錄資訊。 -
QSqlQueryModel
、QSqlTableModel
和QSqlRelationalTableModel
:存取資料庫資料。
正如上面所說,如果這些標準模型不能滿足你的需要,就必須繼承QAbstractItemModel
、QAbstractListModel
或者QAbstractTableModel
,建立自己的模型類。
Qt 還提供了一系列預定義好的檢視:QListView
用於顯示列表,QTableView
用於顯示錶格,QTreeView
用於顯示層次資料。這些類都是QAbstractItemView
的子類。這意味著,如果你要建立新的檢視類,則可以繼承QAbstractItemView
。
則是所有委託的抽象基類。自 Qt 4.4 依賴,預設的委託實現是
QAbstractItemDelegateQStyledItemDelegate
。但是,QStyledItemDelegate
和QItemDelegate
都可以作為檢視的編輯器,二者的區別在於,QStyledItemDelegate
使用當前樣式進行繪製。在實現自定義委託時,推薦使用QStyledItemDelegate
作為基類,或者結合
Qt style sheets。
如果你覺得 model/view 模型過於複雜,或者有很多功能是用不到的,Qt 還有一系列方便使用的類。這些類都是繼承自標準的檢視類,並且繼承了標準模型。這些類並不是為其他類繼承而準備的,只是為了使用方便。它們包括QListWidget
、QTreeWidget
和QTableWidget
。這些類遠不如檢視類靈活,不能使用另外的模型,因此只適用於簡單的情形。
相關文章
- MCV結構
- MCV & Develop:2014年全球遊戲行業平均年薪超30萬元dev遊戲行業
- 軟體測試模型-其他模型 (W 模型|H 模型|X 模型)模型
- 模型壓縮-模型蒸餾、模型剪枝、模型量化模型
- 【大模型】模型安全大模型
- 基座模型、聊天模型和指令模型的區別模型
- 機器學習引數模型與非引數模型/生成模型與判別模型機器學習模型
- 軟體開發模型/原型法/瀑布模型/螺旋模型模型原型
- 10django模型[模型類]Django模型
- 生成模型與判別模型模型
- 軟體測試模型-瀑布模型模型
- 軟體測試模型-V 模型模型
- 軟體測試模型-敏捷模型模型敏捷
- 從貧血模型到充血模型模型
- DOM 模型(文件物件模型)重點模型物件
- 理解BW資料模型 - DSO模型模型
- 軟體測試中的V模型、W模型和H模型模型
- 因果模型:邊緣結構模型MSM模型
- 【模型推理】Tengine 模型轉換及量化模型
- OSI模型 與 DOD模型的比較模型
- 鴻蒙HarmonyOS實戰-Stage模型(程序模型)鴻蒙模型
- 四 阿里大模型接入:模型微調阿里大模型
- Reactor模型React模型
- 索引模型索引模型
- IO模型模型
- 【JVM】模型JVM模型
- NIO模型模型
- Django 模型Django模型
- 機器學習模型機器學習模型
- 遊戲化三部曲:核心模型、輔助模型和成長模型遊戲模型
- 資料倉儲 - 星座模型、星型模型和雪花模型的介紹模型
- 統一監聽所有模型的模型事件模型事件
- 《機器學習_05_線性模型_最大熵模型》機器學習模型熵
- 故障模型哪家強?PDR 模型來幫忙模型
- 圖解協程排程模型-GMP模型圖解模型
- 信貸風控模型開發----模型簡介模型
- 標準盒模型和怪異盒模型模型
- IO模型學習(一)IO模型分類模型