一、概述
QStandardItemModel是QAbstractItemModel的派生類,用於在Model/View架構中存儲自定義數據的通用模型,可以用於在任何支持QAbstractItemModel接口的view(例如QListView、QTableView和QTreeView,以及自定義視圖)中作為數據存儲。
QStandardItemModel可以用作標准Qt數據類型的數據存儲Model。QStandardItemModel提供了一種經典的基於項的方法來處理模型中的數據。QStandardItemModel模型中的項對應類型必須為QStandardItem。
二、定義方法
定義QStandardItemModel對象的方法:
- QStandardItemModel(parent: QObject = None)
- QStandardItemModel(int rows, int columns, parent: QObject = None)
方法一定義一個QStandardItemModel對象,未指定行數和列數,實際上構造的是一個空的QStandardItemModel對象,后續可以使用appendRow()、insertRow()在添加數據項。
方法二定義了一個指定行數和列數的QStandardItemModel對象,但具體數據項同樣未初始化,可以通過setItem方法進行初始化。
三、數據添加
在view對應的數據存儲初始化時,通常創建一個空的QStandardItemModel對象,並使用appendRow()、insertRow()添加一行數據項。
對應語法如下:
- appendRow(Iterable[QStandardItem])
- void appendRow(QStandardItem item)
- void insertRow(int row, Iterable[QStandardItem] ))
- void insertRow(int row, QStandardItem item)
- bool insertRow(int row, parent:QModelIndex =QModelIndex())
注意:
- 使用appendRow、insertRow時,數據項必須是QStandardItem類型,QStandardItem創建時存儲的真正數據必須是文本字符串型,其他類型必須先進行類型轉換
- insertRow插入行時可以先不添加數據項(使用insertRow(int row, QModelIndex parent=QModelIndex())),后續通過setItem再設置對應數據項
- Qt的QList類型在PyQt中不支持,凡是QList類型的變量可以使用Python的任何可迭代類型替代,上述語法中的
Iterable[QStandardItem]
表示一個存儲元素類型為QStandardItem的可迭代類型如列表,這樣一次可以添加一行多個字段的數據 - 同一個QStandardItem數據項不能在一個視圖中添加兩次,否則后面一次的調用實際上是沒有添加數據項
- insertRow的參數行號必須是當前已經存在的數據行號(從0開始計數),否則將返回None或False
四、數據項查詢
4.1、item()
使用item()方法訪問QStandardItemModel對象中的項,語法如下:
- QStandardItem item(int row, int column = 0)
通過item方法還可以返回指定行和列對應的數據項。
4.2、text()
知道一個QStandardItemModel對象中的數據項以后,可以通過該數據項的text()方法獲取對應數據的值。語法如下:
- str QStandardItem.text()
五、數據修改
5.1、setItem()設置數據項
可以使用setItem()將數據指定到對應的行和列的位置,語法如下:
- setItem(int row, int column, QStandardItem item)
該方法將QStandardItemModel對象中對應行和列位置的數據項設置為新的參數item對應項,如果原來未指定項,則相當於數據項初始化,否則就是替換原有數據項。
5.2、查詢數據項+setText()修改數據項的值
如果一個QStandardItemModel對象中對應行和列位置的數據項已經設置,但需要修改該數據項數據的值,可以使用setText()來修改該數據項的值。語法如下:
- setText(str text)
其中參數text就是要修改數據的對應字符串值。
六、刪除數據
要刪除QStandardItemModel對象中對應的數據,可以使用removeRow,語法如下:
- removeRow(int row,QModelIndex parent=QModelIndex())
參數row指明要刪除的數據行,parent表示要刪數據的父節點,對於樹形視圖來說需要使用,對於鏈表視圖和表格視圖用缺省值即可。
七、其他方法
- 可以使用setRowCount()和setColumnCount()更改該對象的行數和列數
- 可以使用insertColumn()按列插入數據項,使用removeColumn()按列刪除數據項
- 可以使用setHorizontalHeaderLabels()和setVerticalHeaderLabels()設置QStandardItemModel對象的標題標簽
- 可以使用findItems()在QStandardItemModel對象中搜索符合要求的數據項,並通過調用sort()對QStandardItemModel對象中的數據項進行排序
- 可以調用clear()方法刪除QStandardItemModel對象的所有數據項
- 可以使用index()方法獲取對應數據項的索引數據,可參考《PyQt學習隨筆:Qt中Model/View中的Model Index》
七、案例
本案例實現了一個initViewData方法,將一個窗口的listView對象(對象名為Designer缺省名listView,沒有修改)和tableView對象(對象名為Designer缺省名tableView,沒有修改)使用同一個存儲Model,model對象名為 self.itemModel ,設置為3列,3列數據組成為:數字序號+‘:‘+20個數字和空格字符串,行數為18行。
l = [(digit, ": ", (str(digit) + ' ') * 20) for digit in range(1, 10)]
self.itemModel = QtGui.QStandardItemModel()
self.itemModel.setColumnCount(3)
for line in l:
record = []
for col in line:
item = QtGui.QStandardItem(str(col))
record.append(item)
ret = self.itemModel.insertRow(0,record)
ret = self.itemModel.appendRow( record)
self.listView.setModel(self.itemModel)
self.tableView.setModel(self.itemModel)
運行截圖如下:
可以看到只有前9行生成了數據,后9行無數據,因為代碼中appendRow的數據是前面insertRow已經處理了數據項列表,不能重復插入,但對應插入導致Model的行數被擴充。