Qt學習記錄--01 Qt的model/view架構介紹

一 引入:

        有時,我們的系統需要顯示大量數據,比如從數據庫中讀取數據,以自己的方式顯示在自己的應用程序的界面中。早期的 Qt 要實現這個功能,需要定義一個組件,在這個組件中保存一個數據對象,比如一個列表。我們對這個列表進行查找、插入等的操作,或者把修改的地方寫回,然後刷新組件進行顯示。這個思路很簡單,也很清晰,但是對於大型程序,這種設計就顯得蒼白無力。比如,在一個大型系統中,你的數據可能很大,全部存入一個組件的數據對象中,效率會很低,並且這樣的設計也很難在不同組件之間共享數據。如果你要幾個組件共享一個數據對象,要麼你就要用存取函數公開這個數據對象,要麼你就必須把這個數據對象放進不同的組件分別進行維護。

       Smalltalk 語言發明了一種嶄新的實現,用來解決這個問題,這就是著名的 MVC 模型。對這個模型無需多言。MVC 是  Model-View-Controller 的簡寫,即模型-視圖-控制器。在 MVC 中,模型負責獲取需要顯示的數據,並且存儲這些數據的修改。每種數據類型都有它自己對應的模型,但是這些模型提供一個相同的 API,用於隱藏內部實現。視圖用於將模型數據顯示給用戶。對於數量很大的數據,或許只顯示一小部分,這樣就能很好的提高性能。控制器是模型和視圖之間的媒介,將用戶的動作解析成對數據的操作,比如查找數據或者修改數據,然後轉發給模型執行,最後再將模型中需要被顯示的數據直接轉發給視圖進行顯示。MVC 的核心思想是分層,不同的層應用不同的功能。


二 Qt的model/view架構介紹:

        Qt 4 開始,引入了類似的 model/view 架構來處理數據和麪向最終用戶的顯示之間的關係。當 MVC 的 V 和 C 結合在一起,我們就得到了 model/view 架構。這種架構依然將數據和界面分離,但是框架更爲簡單。同樣,這種架構也允許使用不同界面顯示同一數據,也能夠在不改變數據的情況下添加新的顯示界面。爲了處理用戶輸入,我們還引入了委託(delegate)。引入委託的好處是,我們能夠自定義數據項的渲染和編輯。

   Model View 概覽
Model View 概覽

        如上圖所示,模型與數據源進行交互,爲框架中其它組件提供接口。這種交互的本質在於數據源的類型以及模型的實現方式。視圖從模型獲取模型索引,這種索引就是數據項的引用。通過將這個模型索引反向傳給模型,視圖又可以從數據源獲取數據。在標準視圖中,委託渲染數據項;在需要編輯數據時,委託使用直接模型索引直接與模型進行交互。

        總的來說,model/view 架構將傳統的 MV 模型分爲三部分:模型、視圖和委託。每一個組件都由一個抽象類定義,這個抽象類提供了基本的公共接口以及一些默認實現。模型、視圖和委託則使用信號槽進行交互:

                   ● 來自模型的信號通知視圖,其底層維護的數據發生了改變;

                   ● 來自視圖的信號提供了有關用戶與界面進行交互的信息;

                   ● 來自委託的信號在用戶編輯數據項時使用,用於告知模型和視圖編輯器的狀態。

        所有的模型都是QAbstractItemModel的子類。這個類定義了供視圖和委託訪問數據的接口。模型並不存儲數據本身。這意味着,你可以將數據存儲在一個數據結構中、另外的類中、文件中、數據庫中,或者其他你所能想到的東西中。我們將在後面再詳細討論這些內容。

    QAbstractItemModel提供的接口足夠靈活,足以應付以表格、列表和樹的形式顯示的數據。但是,如果你需要爲列表或者表格設計另外的模型,直接繼承QAbstractListModelQAbstractTableModel類可能更好一些,因爲這兩個類已經實現了很多通用函數。關於這部分內容,我們也會在後文中詳述。

        Qt 內置了許多標準模型:

            ● QStringListModel存儲簡單的字符串列表。

            ● QStandardItemModel:可以用於樹結構的存儲,提供了層次數據。

            ● QFileSystemModel:本地系統的文件和目錄信息。

            ● QSqlQueryModelQSqlTableModelQSqlRelationalTableModel:存取數據庫數據。

        正如上面所說,如果這些標準模型不能滿足你的需要,就必須繼承QAbstractItemModel、 QAbstractListModel 或者QAbstractTableModel,創建自己的模型類。

        Qt 還提供了一系列預定義好的視圖QListView用於顯示列表,QTableView用於顯示錶格,QTreeView用於顯示層次數據。這些類都是QAbstractItemView的子類。這意味着,如果你要創建新的視圖類,則可以繼承QAbstractItemView
    QAbstractItemDelegate
則是所有委託的抽象基類自 Qt 4.4 以來,默認的委託實現是QStyledItemDelegate。但是,QStyledItemDelegateQItemDelegate都可以作爲視圖的編輯器,二者的區別在於,QStyledItemDelegate使用當前樣式進行繪製。在實現自定義委託時,推薦使用QStyledItemDelegate作爲基類,或者結合 Qt style sheets。

        如果你覺得 model/view 模型過於複雜,或者有很多功能是用不到的,Qt 還有一系列方便使用的類。這些類都是繼承自標準的視圖類,並且繼承了標準模型。這些類並不是爲其他類繼承而準備的,只是爲了使用方便。它們包括QListWidgetQTreeWidgetQTableWidget。這些類遠不如視圖類靈活,不能使用另外的模型,因此只適用於簡單的情形。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章