Qt 常用类——QStandardItemModel
轉(zhuǎn)載:落葉知秋時
類QabstractItemModel,QabstractListModel,QAbstractTableModel不保存數(shù)據(jù),用戶需要從這些類派生出子類,并在子類中定義某種數(shù)據(jù)結(jié)構(gòu)來保存數(shù)據(jù)。
與此不同,類QStandardItemModel負責保存數(shù)據(jù),每個數(shù)據(jù)項被表示為類QStandardItem的對象。接下來,我們主要從兩個方面介紹類QStandardItemMode的內(nèi)容。
首先來看第一方面:
如前文所述,一個數(shù)據(jù)項由若干個『角色,數(shù)據(jù)子項』對組成。類QStandardItem負責保存、訪問這些數(shù)據(jù)。該類的內(nèi)部定義了一個類型為QVector的容器,
每個容器元素本質(zhì)上存放一個『角色,數(shù)據(jù)子項』對。由于各個角色對應(yīng)的數(shù)據(jù)子項可能具有不同的類型,Qt使用QVariant來存放每個數(shù)據(jù)子項。
當用戶希望將一些數(shù)據(jù)存放在一個QStandardItem對象中時,可以調(diào)用其成員函數(shù):
void setData ( const QVariant & value, int role) //將『role, value』對存入。當用戶希望讀取該對象中的數(shù)據(jù)時,可以調(diào)用另外一個成員函數(shù):
QVariant data ( int role = ) const //讀取角色role對應(yīng)的數(shù)據(jù)子項。以上兩個函數(shù)是QStandardItem的核心。有了這兩個函數(shù),我們就可以訪問該類所表示數(shù)據(jù)項的任何一個『角色,數(shù)據(jù)子項』對。然而,對于一些常用角色,
該類提供了更加簡潔、容易記憶的成員函數(shù)。例如,當一個數(shù)據(jù)項被顯示在視圖中時,它往往包含一些文字、一個圖標,還可能包含一個復選框。
常用角色:
- Qt::BackgroundRole控制顯示背景,
- Qt::FontRole控制文字字體,
- Qt::ForegroundRole控制文字顏色,
- Qt::CheckStateRole控制復選框的狀態(tài)。
該類提供的一組成員函數(shù)可以方便地訪問這些常用角色對應(yīng)的數(shù)據(jù)子項:
- 成員函數(shù)setBackground()、background()分別設(shè)置/返回背景刷子。
- 函數(shù)setFont()、font()分別設(shè)置/返回文字字體。
- 函數(shù)setForeground()、foreground()分別設(shè)置/返回字體顏色。
- 函數(shù)setCheckState()、checkState()分別設(shè)置/返回復選框狀態(tài)。
然后再來看第二方面:
類QStandardItemModel將類QStandardItem表示的數(shù)據(jù)項組織起來,形成列表、表格、樹甚至更復雜的數(shù)據(jù)結(jié)構(gòu)。
- 該類提供了一組成員函數(shù),向這些數(shù)據(jù)結(jié)構(gòu)添加新的數(shù)據(jù)項,更改已經(jīng)存在的數(shù)據(jù)項,或者刪除已有的數(shù)據(jù)項。
- 另一方面,作為一個模型類,它實現(xiàn)了QAbstractItemModel定義的接口函數(shù),以使其他視圖類能夠訪問模型中的數(shù)據(jù)項。
1:如果數(shù)據(jù)集被表示為一個列表,我們可以調(diào)用類QStandardItemModel的成員函數(shù)appendRow()向列表中添加一個數(shù)據(jù)項,使用item()讀取一個數(shù)據(jù)項。
如代碼段13-10所示。
- 行①獲取模型最頂層的根節(jié)點,
- 行②創(chuàng)建一個QStandardItem對象,表示一個數(shù)據(jù)項,
- 行③將該數(shù)據(jù)項作為根節(jié)點的子節(jié)點添加到列表中。
行②的構(gòu)造函數(shù)在內(nèi)部調(diào)用該類的setData()函數(shù),將行②的QString對象作為Qt::DisplayRole對應(yīng)的數(shù)據(jù)子項存入新構(gòu)造的對象。
由于數(shù)據(jù)集本身是一個列表,所以我們使用QListView顯示該數(shù)據(jù)集,讀者可以運行該例子查看顯示結(jié)果。
代碼段13-10:使用QStandardItemModel處理列表
QStandardItemModel listModel;QStandardItem *rootItem = listModel.invisibleRootItem(); // 行1for (int row = 0; row < 4; ++row){QStandardItem *item = new QStandardItem(QString("%1").arg(row) ); // 行2rootItem->appendRow( item ); //行3}QListView listView;listView.setModel ( & listModel );
2:如果數(shù)據(jù)集被表示為一個表格,可以調(diào)用類QStandardItemModel的成員函數(shù)setItem()設(shè)定表格中的某個數(shù)據(jù)項,如代碼段13-11所示。
由于這個代碼段中的數(shù)據(jù)集是一個表格,所以使用QTableView顯示該數(shù)據(jù)集。
代碼段13-11:使用QStandardItemModel處理表格
QStandardItemModel tableModel(4, 4);for (int row = 0; row < 4; ++row){for (int column = 0; column < 4; ++column) {QStandardItem *item = new QStandardItem(QString("%0,%1").arg(row).arg(column));tableModel.setItem(row, column, item);}}QTableView tableView;tableView.setModel( & tableModel );
?
3:如果數(shù)據(jù)集被表示為一個樹,可以調(diào)用類QStandardItemModel的成員函數(shù)appendRow()向某個樹節(jié)點添加子節(jié)點。
通過多次調(diào)用該函數(shù),可以構(gòu)建一棵復雜的樹。代碼段13-12構(gòu)建一棵簡單的樹:最頂層的根節(jié)點有一個文字內(nèi)容為“0”的子節(jié)點,
該子節(jié)點有一個文字內(nèi)容為“1”的子節(jié)點。依此類推,“1”子節(jié)點有一個“2”子節(jié)點,“2”子節(jié)點有一個“3”子節(jié)點,形成一棵深度為4的樹。
這棵樹的每個節(jié)點都沒有兄弟節(jié)點(具有相同父節(jié)點的多個節(jié)點被相互稱為兄弟節(jié)點),感興趣的讀者可以修改這段代碼,以使其中某些節(jié)點具有兄弟節(jié)點。
由于數(shù)據(jù)集是一棵樹,我們使用QTreeView顯示它。
代碼段13-12,使用QStandardItemModel處理樹:
QStandardItemModel treeModel; QStandardItem *parentItem = treeModel.invisibleRootItem(); for (int i = 0; i < 4; ++i) {QStandardItem *item = new QStandardItem(QString("%0").arg(i));parentItem->appendRow(item);parentItem = item; } QTreeView treeView; treeView.setModel( & treeModel );類QStandardItemModel之所以能夠表示列表、表格、樹甚至更復雜的數(shù)據(jù)結(jié)構(gòu),得益于類QStandardItem在其內(nèi)部定義了一個類型為
QVector<QStandardItem*>的容器,可以將每個容器元素所指的QStandardItem對象設(shè)定為子對象。表現(xiàn)在如圖13-13所示的類圖上,類QStandardItem和自身具有“children”關(guān)系。一個類和自身發(fā)生關(guān)聯(lián),在UML中被稱為自關(guān)聯(lián)(self association)。類QStandardItemModel定義了一個名為root的數(shù)據(jù)成員,邏輯上是一個指向QStandardItem對象的指針。這個對象可以設(shè)定多個QStandardItem的對象作為自己的子對象,而其中每個子對象又可以包含其他的子對象。依此類推,這棵樹可以具有任意深度,每個父對象可以包含任意多個子對象。
?
?
很自然地,QStandardItemModel可以使用QStandardItem表示具有樹狀數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)集,如圖13-14所示。
圖中的每個小方框表示類QStandardItem的一個對象。如果小方框的邊線為虛,相應(yīng)的QStandardItem對象并不表示數(shù)據(jù)集中的任何數(shù)據(jù),僅被用來表示某種數(shù)據(jù)結(jié)構(gòu)。如果小方框的邊線為實,相應(yīng)的QStandardItem對象就表示數(shù)據(jù)集中的一個數(shù)據(jù)項。在右側(cè)的圖中,QStandardItemModel的數(shù)據(jù)成員root所指的對象表示一個不可見的根,而數(shù)據(jù)集的根(圖中結(jié)點G)被表示為這個不可見根的一個子節(jié)點。
?
?
列表被看作一個特殊的樹:不可見根具有若干個子節(jié)點,每個子節(jié)點表示列表中的一個數(shù)據(jù)項,不再包含任何子節(jié)點,如該圖左側(cè)所示。
而表格的表示方式反而麻煩一些。不可見根含有若干子節(jié)點(圖中A,B,C),這些子節(jié)點并不表示數(shù)據(jù)集中的任何數(shù)據(jù)項。
第i個子節(jié)點會包含若干子節(jié)點(比如圖中D,E,F),這些子節(jié)點才表示表格第i行的數(shù)據(jù)項。
最后再討論一下QStandardItemModel表示數(shù)據(jù)集的優(yōu)缺點:
使用QStandardItemModel表示數(shù)據(jù)集具有以下優(yōu)點:
然而,這種表示方法也有局限性:
- 當數(shù)據(jù)集中的數(shù)據(jù)項很多時,施加在數(shù)據(jù)集上的某些操作的執(zhí)行效率會很低。
? ? ? 比如,設(shè)數(shù)據(jù)集是一個1萬行、20列的表格,其中第10列存放的是浮點數(shù)。如果我們想計算這一列的平均值,按照圖13-14,這需要遍歷所有行,
取得第10列的QStandardItem對象,再依據(jù)角色“Qt::DisplayRole”取得對應(yīng)的數(shù)據(jù)子項。由于這個數(shù)據(jù)子項的類型為QString,還需要將其轉(zhuǎn)換為浮點數(shù),
最后求所有浮點數(shù)的平均值。這些操作會耗費較長的時間。
因此,對于數(shù)據(jù)量不是很大、對性能要求不是很高的場合,我們可以使用類QStandardItemModel來表示一個數(shù)據(jù)集。
否則,用戶應(yīng)該從QAbstractItemModel、QAbstractListModel或者QAbstractTableModel派生新類,自行管理數(shù)據(jù)集的存放與訪問。
轉(zhuǎn)載于:https://www.cnblogs.com/fuqia/p/8908182.html
總結(jié)
以上是生活随笔為你收集整理的Qt 常用类——QStandardItemModel的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 河南大学软件学院宿舍楼综合布线设计方案
- 下一篇: EPSON 自带CCD图像处理包使用举例