Pyqt中View類別容器和Widget類別容器的區別
簡介
在beta迭代中,我們選擇用pyqt5來重寫alpha迭代中使用tkinter庫編寫的界面。
按鈕之類的與tkiner使用無異,在顯示“測試報告”和“測試隊列”這方面,我打算使用列表類控件,但是在qt designer中發現了兩個看起來類似的控件:QListView和QListWidget。這兩個控件有什么區別呢? 從文檔中我得知,QListWidget是繼承自QListView的,其他Widget容器也是繼承自對應View容器,而QListView是繼承自一個抽象基類QAbastractItemView(python中采用@abstractmethod實現),三者之間有着以下關系:

但是知道QListView是QListWidget的一個子類,只是知道了他們的聯系,似乎還是不能直觀反映他們的區別。
我們能從網上找到一個不錯的解釋:
QListView 里沒有自己的"模型"要自己建模來保存數據,這可以很大程度上降低數據冗余,提高程序的效率.但是要求我們對view/model框架比較了解,不適合新手使用.
QListWidget是QListView的子類,在QListWidget中已經幫我們定義好了一個模型.這個模型非常方便,十分全面.這樣就可以直接在QListWidget里面添加數據,而不用在從新制定一個模型了.十分方便.其實QListView和QListWidget的主要區別就是有木有自己的模型而已.
View類別容器和Widget類別容易主要區別就在於“模型”。那么什么是模型呢?模型是將數據從視圖中分離出來的產物,提供和數據交互的接口。Widget類型容器內置了一個簡單的模型,我們可以直接調用實例的addItem()、addItems()方法來給Widget添加元素,相應變化會直接反映到界面上。而View類別采用了所謂的view/model框架,對視圖和數據進行了分離、解耦。Widget部件並沒有被設計為可以從視圖中分離數據。View類型和Widgt類型看起來相同,但它們與數據的交互方式不同。
view/model框架
view/model框架是qt在qt4以后的版本中用來處理數據和面向用戶的最終顯示的之間的關系,這種架構也允許使用不同界面顯示同一數據,也能夠在不改變數據的情況下添加新的顯示界面,而這是普通的widget類控件做不到的。除了view和model以外,qt還引入了委托(delegate),用來自定義數據項的渲染和編輯。三者的關系如下:

由於我們組項目目前階段數據的展示較為簡單,選擇了相對易用的QListWidget作為顯示數據的方式,因此還未對view/model框架和委托有較為深入的研究。
模型
所有的模型都是QAbstractItemModel的子類。這個類定義了供視圖和委托訪問數據的接口。模型並不存儲數據本身。這意味着可以將數據存儲在一個數據結構中、另外的類中、文件中、數據庫中,或者其他所能想到的東西中。
QAbstractItemModel提供的接口足夠靈活,足以應付以表格、列表和樹的形式顯示的數據。但是,如果需要為列表或者表格設計另外的模型,直接繼承QAbstractListModel和QAbstractTableModel類可能更好一些,因為這兩個類已經實現了很多通用函數。
Qt 內置了許多標准模型:
QStringListModel:存儲簡單的字符串列表。QStandardItemModel:可以用於樹結構的存儲,提供了層次數據。QFileSystemModel:本地系統的文件和目錄信息。QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel:存取數據庫數據。
如果這些標准模型不能滿足需要,就必須繼承QAbstractItemModel、QAbstractListModel或者QAbstractTableModel,創建自己的模型類。
