關於 QAbstractItemModel 學習的一點分享

關於 QAbstractItemModel 學習的一點分享

簡介:

Qt的模型、視圖框架對處理一些複雜數據結構的可視化非常有用。

Qt提供了三種常用的數據模型:QAbstractListModel (表單模型)、QAbstractTableModel (表格模型)、QAbstractItemModel (項目模型)。
其中第三種模型最靈活。前兩種模型都是繼承第三種模型的類的。

Qt的幫助文檔裏有提到:

If you need a model to use with an item view such as QML’s List View element or the C++ widgets QListView or QTableView, you should consider subclassing QAbstractListModel or QAbstractTableModel instead of this class.

可以看出,如果是listView 或者 tableView 那麼就考慮前兩種數據模型,但是如果是treeView,那就只好選擇QAbstractItemModel (項目模型)了。

可以這樣理解,QAbstractListModel 是QAbstractTableModel 的特殊化,QAbstractTableModel 是QAbstractItemModel 的特殊化。

接下來,我們着中來理解下QAbstractItemModel類。

關於QAbstractItemModel類的細節描述:

1、QAbstractItemModel 類提供了共模型視圖框架中的其他組件訪問的接口。

2、使用QAbstractItemModel 類,應當子類化。不能直接創建該類的對象。

3、AbstractItemModel 類 支持的 The underlying data model (底層的數據模型)是一個類似hierarchy of tables(有層級關係的表格),如果沒有層級,那就只有rows(行) 和colums(列)。但在AbstractItemModel 類中,還有QModelIndex(索引),這樣,每一個Item 就是一個獨立的表格單元。如下圖:

在這裏插入圖片描述
4、對於每一個數據單元(item of data)可以通過index() 索引,它的子項可以通過sibling()索引,它的父項可以通過parent()索引。

5、對於每一個數據單元都有一些data elements(數據元素)來界定( Qt::ItemDataRole)數據的角色。該數據元素可以通過data()放來來獲取:

如:
QVariant str = item2->data(Qt::ToolTipRole);

qDebug()<<str;

下表列出了數據角色:

在這裏插入圖片描述
什麼是數據角色?可以這樣理解對於每個item呈現給用戶的視角是多方面的,比如:ToolTipRole 角色中的數據是隻有當鼠標移到視圖中多對應的Item纔會顯示。
例如,下圖中選中的Item中 有三個角色,分別是藍色的圖標、字符"B"、提示“”indexB“”。
在這裏插入圖片描述
6、在每一個item中,每個數據角色會對應一個數據,通過setData()方法來爲指定的數據角色設定數據。setItemData()方法 則是爲所有的數據角色設定相同的數據。

7、hasChildren()方法可以確認是否有子項。

8、對於一個層級的表格,都有關於行和列的操作
rowCount() 、columnCount()、 insertRows(), insertColumns(), removeRows(), and removeColumns().

9 、該模型該提供了一些信號來表示數據的變化:dataChanged()、headerDataChanged() 、layoutChanged()

子類化該模型

1、在只讀模型和基本的可編輯模型中,至少需要重寫index(), parent(), rowCount(), columnCount(), data()這些函數。

2、重寫 hasChildren()函數來提供一些特殊的模型的行爲。

3、如果模型是可編輯的,那麼還需要重載setData() 和 flags().

4、重寫headerData()和setHeaderData()對標題進行編輯。

5、在setData()和setHeaderData()函數中必須明確的加載 dataChanged() and headerDataChanged() 信號。

6、對於自定義模型,需要創建模型的索引,這裏會用到createIndex()。

7、模型的重構會用到插入刪除行列insertRows(), removeRows(), insertColumns(),and removeColumns(). 在這些操作中it is important to notify any connected views about changes to the model’s dimensions both before and after they occur:

例如:

bool TreeModel::insertColumns(int position, int columns, const QModelIndex &parent)
{
    beginInsertColumns(parent, position, position + columns - 1);
    const bool success = rootItem->insertColumns(position, columns);
    endInsertColumns();

    return success;
}

8、重寫fetchMore() and canFetchMore()使數據模型遞增。

有關子類化的相關實現 可以參考Qt的示例代碼:Simple Tree Model

在Qt的幫助文檔中還有一篇 Model/View Programming 的介紹,該文檔中Model Subclassing Reference 就有提到如何子類化。

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