13.2.4  QStandardItemModel(1)

类QabstractItemModel,QabstractListModel,QAbstractTableModel不保存数据,用户需要从这些类派生出子类,并在子类中定义某种数据结构来保存数据。与此不同,类QStandardItemModel负责保存数据,每个数据项被表示为类QStandardItem的对象。我们首先阐述如何使用类QStandardItem保存一个数据项,再阐述如何使用类QStandardItemModel将这些数据项组织起来,形成列表、表格或者树,以供其他视图类显示。

如前文所述,一个数据项由若干个『角色,数据子项』对组成。类QStandardItem负责保存、访问这些数据。该类的内部定义了一个类型为QVector的容器,每个容器元素本质上存放一个『角色,数据子项』对。

由于各个角色对应的数据子项可能具有不同的类型,Qt使用QVariant来存放每个数据子项。当用户希望将一些数据存放在一个QStandardItem对象中时,可以调用其成员函数:

 
  
  1. void setData ( const QVariant & value, int role) 

 

将『role, value』对存入。当用户希望读取该对象中的数据时,可以调用另外一个成员函数:

 
  
  1. QVariant data ( int role = ) const 

读取角色role对应的数据子项。

以上两个函数是QStandardItem的核心。有了这两个函数,我们就可以访问该类所表示数据项的任何一个『角色,数据子项』对。然而,对于一些常用角色,该类提供了更加简洁、容易记忆的成员函数。例如,当一个数据项被显示在视图中时,它往往包含一些文字、一个图标,还可能包含一个复选框。角色Qt::BackgroundRole控制显示背景,Qt::FontRole控制文字字体,Qt::ForegroundRole控制文字颜色,Qt::CheckStateRole控制复选框的状态。该类提供的一组成员函数可以方便地访问这些常用角色对应的数据子项。成员函数setBackground()、background()分别设置/返回背景刷子。函数setFont()、font()分别设置/返回文字字体。函数setForeground()、foreground()分别设置/返回字体颜色。函数setCheckState()、checkState()分别设置/返回复选框状态。

类QStandardItemModel将类QStandardItem表示的数据项组织起来,形成列表、表格、树甚至更复杂的数据结构。该类提供了一组成员函数,向这些数据结构添加新的数据项,更改已经存在的数据项,或者删除已有的数据项。另一方面,作为一个模型类,它实现了QAbstractItemModel定义的接口函数,以使其他视图类能够访问模型中的数据项。

如果数据集被表示为一个列表,我们可以调用类QStandardItemModel的成员函数appendRow()向列表中添加一个数据项,使用item()读取一个数据项,如代码段13 10所示。行①获取模型最顶层的根节点,行②创建一个QStandardItem对象,表示一个数据项,行③将该数据项作为根节点的子节点添加到列表中。行②的构造函数在内部调用该类的setData()函数,将行②的QString对象作为Qt::DisplayRole对应的数据子项存入新构造的对象。由于数据集本身是一个列表,所以我们使用QListView显示该数据集,读者可以运行该例子查看显示结果。

代码段13 10,使用QStandardItemModel处理列表,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp

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

如果数据集被表示为一个表格,可以调用类QStandardItemModel的成员函数setItem()设定表格中的某个数据项,如代码段13 11所示。由于这个代码段中的数据集是一个表格,所以使用QTableView显示该数据集。

代码段13 11,使用QStandardItemModel处理表格,取自z:\examples\mvc\QStandardItemModel_demo\main.cpp

 

 
  
  1. QStandardItemModel tableModel(4, 4);  
  2.     for (int row = 0; row < 4; ++row) {  
  3.          for (int column = 0; column < 4; ++column) {  
  4.              QStandardItem *item = new QStandardItem(  
  5.                  QString("%0,%1").arg(row).arg(column));  
  6.              tableModel.setItem(row, column, item);  
  7.          }  
  8.     }     
  9.     QTableView tableView;  
  10.     tableView.setModel( & tableModel );  

如果数据集被表示为一个树,可以调用类QStandardItemModel的成员函数appendRow()向某个树节点添加子节点。通过多次调用该函数,可以构建一棵复杂的树。代码段13 12构建一棵简单的树:最顶层的根节点有一个文字内容为"0"的子节点,该子节点有一个文字内容为"1"的子节点。依此类推,"1"子节点有一个"2"子节点,"2"子节点有一个"3"子节点,形成一棵深度为4的树。这棵树的每个节点都没有兄弟节点(具有相同父节点的多个节点被相互称为兄弟节点),感兴趣的读者可以修改这段代码,以使其中某些节点具有兄弟节点。由于数据集是一棵树,我们使用QTreeView显示它。

 

本文来源:http://book.51cto.com/art/201207/347880.htm