溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

QStandardItem and QStandardItemModel Class Reference

發(fā)布時(shí)間:2020-07-25 03:51:49 來源:網(wǎng)絡(luò) 閱讀:691 作者:844133395 欄目:編程語言

        類QabstractItemModel,QabstractListModel,QAbstractTableModel不保存數(shù)據(jù),用戶需要從這些類派生出子類,并在子類中定義某種數(shù)據(jù)結(jié)構(gòu)來保存數(shù)據(jù)。與此不同,類QStandardItemModel負(fù)責(zé)保存數(shù)據(jù),每個(gè)數(shù)據(jù)項(xiàng)被表示為類QStandardItem的對(duì)象。

        我們首先闡述如何使用類QStandardItem保存一個(gè)數(shù)據(jù)項(xiàng),再闡述如何使用類QStandardItemModel將這些數(shù)據(jù)項(xiàng)組織起來,形成列表、表格或者樹,以供其他視圖類顯示。 

        如前文所述,一個(gè)數(shù)據(jù)項(xiàng)由若干個(gè)『角色,數(shù)據(jù)子項(xiàng)』對(duì)組成。類QStandardItem負(fù)責(zé)保存、訪問這些數(shù)據(jù)。該類的內(nèi)部定義了一個(gè)類型為QVector的容器,每個(gè)容器元素本質(zhì)上存放一個(gè)『角色,數(shù)據(jù)子項(xiàng)』對(duì)。 由于各個(gè)角色對(duì)應(yīng)的數(shù)據(jù)子項(xiàng)可能具有不同的類型,Qt使用QVariant來存放每個(gè)數(shù)據(jù)子項(xiàng)。當(dāng)用戶希望將一些數(shù)據(jù)存放在一個(gè)QStandardItem對(duì)象中時(shí),可以調(diào)用其成員函數(shù): 

    void setData ( const QVariant & value, int role) 

將『role, value』對(duì)存入。當(dāng)用戶希望讀取該對(duì)象中的數(shù)據(jù)時(shí),可以調(diào)用另外一個(gè)成員函數(shù):

    QVariant data ( int role = ) const 

讀取角色role對(duì)應(yīng)的數(shù)據(jù)子項(xiàng)。 以上兩個(gè)函數(shù)是QStandardItem的核心。有了這兩個(gè)函數(shù),我們就可以訪問該類所表示數(shù)據(jù)項(xiàng)的任何一個(gè)『角色,數(shù)據(jù)子項(xiàng)』對(duì)。然而,對(duì)于一些常用角色,該類提供了更加簡潔、容易記憶的成員函數(shù)。例如,當(dāng)一個(gè)數(shù)據(jù)項(xiàng)被顯示在視圖中時(shí),它往往包含一些文字、一個(gè)圖標(biāo),還可能包含一個(gè)復(fù)選框。角色Qt::BackgroundRole控制顯示背景,Qt::FontRole控制文字字體,Qt::ForegroundRole控制文字顏色,Qt::CheckStateRole控制復(fù)選框的狀態(tài)。該類提供的一組成員函數(shù)可以方便地訪問這些常用角色對(duì)應(yīng)的數(shù)據(jù)子項(xiàng)。成員函數(shù)setBackground()、background()分別設(shè)置/返回背景刷子。函數(shù)setFont()、font()分別設(shè)置/返回文字字體。函數(shù)setForeground()、foreground()分別設(shè)置/返回字體顏色。函數(shù)setCheckState()、checkState()分別設(shè)置/返回復(fù)選框狀態(tài)。 類QStandardItemModel將類QStandardItem表示的數(shù)據(jù)項(xiàng)組織起來,形成列表、表格、樹甚至更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。該類提供了一組成員函數(shù),向這些數(shù)據(jù)結(jié)構(gòu)添加新的數(shù)據(jù)項(xiàng),更改已經(jīng)存在的數(shù)據(jù)項(xiàng),或者刪除已有的數(shù)據(jù)項(xiàng)。另一方面,作為一個(gè)模型類,它實(shí)現(xiàn)了QAbstractItemModel定義的接口函數(shù),以使其他視圖類能夠訪問模型中的數(shù)據(jù)項(xiàng)。 如果數(shù)據(jù)集被表示為一個(gè)列表,我們可以調(diào)用類QStandardItemModel的成員函數(shù)appendRow()向列表中添加一個(gè)數(shù)據(jù)項(xiàng),使用item()讀取一個(gè)數(shù)據(jù)項(xiàng),如代碼段13 10所示。

行①獲取模型最頂層的根節(jié)點(diǎn),

行②創(chuàng)建一個(gè)QStandardItem對(duì)象,表示一個(gè)數(shù)據(jù)項(xiàng),

行③將該數(shù)據(jù)項(xiàng)作為根節(jié)點(diǎn)的子節(jié)點(diǎn)添加到列表中。行②的構(gòu)造函數(shù)在內(nèi)部調(diào)用該類的setData()函數(shù),將行②的QString對(duì)象作為Qt::DisplayRole對(duì)應(yīng)的數(shù)據(jù)子項(xiàng)存入新構(gòu)造的對(duì)象。由于數(shù)據(jù)集本身是一個(gè)列表,所以我們使用QListView顯示該數(shù)據(jù)集,讀者可以運(yùn)行該例子查看顯示結(jié)果。 代碼段13 10,使用QStandardItemModel處理列表,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp 

QStandardItemModel listModel; 
QStandardItem *rootItem = listModel.invisibleRootItem();//1     
for (int row = 0; row < 4; ++row) {  
    QStandardItem *item = new QStandardItem(QString("%0").arg(row) );//2
    rootItem->appendRow( item );//3
}  
QListView listView; 
listView.setModel ( & listModel );


如果數(shù)據(jù)集被表示為一個(gè)表格,可以調(diào)用類QStandardItemModel的成員函數(shù)setItem()設(shè)定表格中的某個(gè)數(shù)據(jù)項(xiàng),如代碼段13 11所示。由于這個(gè)代碼段中的數(shù)據(jù)集是一個(gè)表格,所以使用QTableView顯示該數(shù)據(jù)集。 代碼段13 11,使用QStandardItemModel處理表格,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp 

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 );

        如果數(shù)據(jù)集被表示為一個(gè)樹,可以調(diào)用類QStandardItemModel的成員函數(shù)appendRow()向某個(gè)樹節(jié)點(diǎn)添加子節(jié)點(diǎn)。通過多次調(diào)用該函數(shù),可以構(gòu)建一棵復(fù)雜的樹。代碼段13 12構(gòu)建一棵簡單的樹:最頂層的根節(jié)點(diǎn)有一個(gè)文字內(nèi)容為“0”的子節(jié)點(diǎn),該子節(jié)點(diǎn)有一個(gè)文字內(nèi)容為“1”的子節(jié)點(diǎn)。依此類推,“1”子節(jié)點(diǎn)有一個(gè)“2”子節(jié)點(diǎn),“2”子節(jié)點(diǎn)有一個(gè)“3”子節(jié)點(diǎn),形成一棵深度為4的樹。這棵樹的每個(gè)節(jié)點(diǎn)都沒有兄弟節(jié)點(diǎn)(具有相同父節(jié)點(diǎn)的多個(gè)節(jié)點(diǎn)被相互稱為兄弟節(jié)點(diǎn)),感興趣的讀者可以修改這段代碼,以使其中某些節(jié)點(diǎn)具有兄弟節(jié)點(diǎn)。由于數(shù)據(jù)集是一棵樹,我們使用QTreeView顯示它。 代碼段13 12,使用QStandardItemModel處理樹,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp 

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之所以能夠表示列表、表格、樹甚至更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),得益于類QStandardItem在其內(nèi)部定義了一個(gè)類型為QVector<QStandardItem*>的容器,可以將每個(gè)容器元素所指的QStandardItem對(duì)象設(shè)定為子對(duì)象。表現(xiàn)在如圖13 13所示的類圖上,類QStandardItem和自身具有“children”關(guān)系。一個(gè)類和自身發(fā)生關(guān)聯(lián),在UML中被稱為自關(guān)聯(lián)(self association)。類QStandardItemModel定義了一個(gè)名為root的數(shù)據(jù)成員,邏輯上是一個(gè)指向QStandardItem對(duì)象的指針。這個(gè)對(duì)象可以設(shè)定多個(gè)QStandardItem的對(duì)象作為自己的子對(duì)象,而其中每個(gè)子對(duì)象又可以包含其他的子對(duì)象。依此類推,這棵樹可以具有任意深度,每個(gè)父對(duì)象可以包含任意多個(gè)子對(duì)象。   很自然地,QStandardItemModel可以使用QStandardItem表示具有樹狀數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)集,如圖13 14所示。圖中的每個(gè)小方框表示類QStandardItem的一個(gè)對(duì)象。如果小方框的邊線為虛,相應(yīng)的QStandardItem對(duì)象并不表示數(shù)據(jù)集中的任何數(shù)據(jù),僅被用來表示某種數(shù)據(jù)結(jié)構(gòu)。如果小方框的邊線為實(shí),相應(yīng)的QStandardItem對(duì)象就表示數(shù)據(jù)集中的一個(gè)數(shù)據(jù)項(xiàng)。在右側(cè)的圖中,QStandardItemModel的數(shù)據(jù)成員root所指的對(duì)象表示一個(gè)不可見的根,而數(shù)據(jù)集的根(圖中結(jié)點(diǎn)G)被表示為這個(gè)不可見根的一個(gè)子節(jié)點(diǎn)。   列表被看作一個(gè)特殊的樹:不可見根具有若干個(gè)子節(jié)點(diǎn),每個(gè)子節(jié)點(diǎn)表示列表中的一個(gè)數(shù)據(jù)項(xiàng),不再包含任何子節(jié)點(diǎn),如該圖左側(cè)所示。而表格的表示方式反而麻煩一些。不可見根含有若干子節(jié)點(diǎn)(圖中A,B,C),這些子節(jié)點(diǎn)并不表示數(shù)據(jù)集中的任何數(shù)據(jù)項(xiàng)。第i個(gè)子節(jié)點(diǎn)會(huì)包含若干子節(jié)點(diǎn)(比如圖中D,E,F(xiàn)),這些子節(jié)點(diǎn)才表示表格第i行的數(shù)據(jù)項(xiàng)。 

        使用QStandardItemModel表示數(shù)據(jù)集具有以下優(yōu)點(diǎn):該類使用QStandardItem存放數(shù)據(jù)項(xiàng),用戶不必定義任何數(shù)據(jù)結(jié)構(gòu)來存放數(shù)據(jù)項(xiàng);QStandardItem使用自關(guān)聯(lián)關(guān)系,能夠表達(dá)列表、表格、樹甚至更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),能夠涵蓋各種各樣的數(shù)據(jù)集;QStandardItem本身存放著多個(gè)『角色,數(shù)據(jù)子項(xiàng)』,視圖類、委托類或者其他用戶定義的類能夠方便地依據(jù)角色訪問各個(gè)數(shù)據(jù)子項(xiàng)。 然而,這種表示方法也有局限性:當(dāng)數(shù)據(jù)集中的數(shù)據(jù)項(xiàng)很多時(shí),施加在數(shù)據(jù)集上的某些操作的執(zhí)行效率會(huì)很低。比如,設(shè)數(shù)據(jù)集是一個(gè)1萬行、20列的表格,其中第10列存放的是浮點(diǎn)數(shù)。如果我們想計(jì)算這一列的平均值,按照?qǐng)D13 14,這需要遍歷所有行,取得第10列的QStandardItem對(duì)象,再依據(jù)角色“Qt::DisplayRole”取得對(duì)應(yīng)的數(shù)據(jù)子項(xiàng)。由于這個(gè)數(shù)據(jù)子項(xiàng)的類型為QString,還需要將其轉(zhuǎn)換為浮點(diǎn)數(shù),最后求所有浮點(diǎn)數(shù)的平均值。這些操作會(huì)耗費(fèi)較長的時(shí)間。 因此,對(duì)于數(shù)據(jù)量不是很大、對(duì)性能要求不是很高的場合,我們可以使用類QStandardItemModel來表示一個(gè)數(shù)據(jù)集。否則,用戶應(yīng)該從QAbstractItemModel、QAbstractListModel或者QAbstractTableModel派生新類,自行管理數(shù)據(jù)集的存放與訪問。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI