首页 > 代码库 > Qt中如何写一个model(自定义一个RowNode,我没有碰到过)

Qt中如何写一个model(自定义一个RowNode,我没有碰到过)

  在qt中,用到最多就是model/view的结构来表示数据层及表示层的关系。model用于给view提供数据。那如何来实现一个简单的树形model呢。

  实现一个自己的model需要重载以下的方法:

[cpp] view plain copy
 
 技术分享技术分享
  1. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;  
  2. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);  
  3. int rowCount(const QModelIndex &parent = QModelIndex()) const;  
  4. int columnCount(const QModelIndex &parent = QModelIndex()) const<pre name="code" class="cpp">QVariant headerData(int section, Qt::Orientation orientation,  
  5.                         int role = Qt::DisplayRole) const;  
  6. bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,  
  7.                        int role = Qt::EditRole);  
  8. QModelIndex index(int row, int column,  
  9.                               const QModelIndex &parent = QModelIndex()) const;  
  10. QModelIndex parent(const QModelIndex &child) const;  
  11. virtual Qt::ItemFlags flags(const QModelIndex &index) const;  

 

下面通过一个小例子来说明每个方法的作用。想实现下面一个树形结构。

 

技术分享

既然实现一个model里面肯定得构造自己的数据结构。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. class RowNode  
  2. {  
  3. public:  
  4.     RowNode() { m_pNode = NULL; }  
  5.     ~RowNode() {}  
  6. public:  
  7.     inline void setParent(RowNode *rowNode) { m_pNode = rowNode; }  
  8.     inline RowNode *parent() { return m_pNode; }  
  9. private:  
  10.     RowNode *m_pNode;  
  11. };  


model构造里

 

 

[cpp] view plain copy
 
 技术分享技术分享
  1. m_child1 = new RowNode();  
  2. m_child2 = new RowNode();  
  3. m_child2->setParent(m_child1);  

 

 

1)data方法:这个方法用于提供model所需要的各种数据。根据不同的index跟role返回不同的值。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;  
  2. {  
  3. <pre name="code" class="cpp">if (Qt::DisplayRole == role)  
  4.     {  
  5.         RowNode *pRowNode = static_cast<RowNode *>(index.internalPointer());  
  6.         if (m_child1 == pRowNode)  
  7.         {  
  8.             if (0 == index.column())  
  9.             {  
  10.                 return "Test";  
  11.             }  
  12.             else if (1 == index.column())  
  13.             {  
  14.                 return "Icon";  
  15.             }  
  16.             else if (2 == index.column())  
  17.             {  
  18.                 return "comboBox";  
  19.             }  
  20.         }  
  21.         else  
  22.         {  
  23.             if (0 == index.column())  
  24.             {  
  25.                 return "col0";  
  26.             }  
  27.             else if (1 == index.column())  
  28.             {  
  29.                 return "col1";  
  30.             }  
  31.             else  
  32.             {  
  33.                 return "col2";  
  34.             }  
  35.         }  
  36.     }  
  37.     else  
  38.         return QVariant();  
  39. }  

 

 

2)setData:这个方法用于设置model的各种数据,根据不同的index跟role的值.原理跟data一样,这里就不直接写了,直接返回True.

 

[cpp] view plain copy
 
 技术分享技术分享
  1. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);  
  2. {  
  3.   return true;  
  4. }  

 

3)rowCount:用于设置行数。需要注意的是返回是指parent下面有几个子,而不是指整个TableView有多少行。因为显示树形的话,返回的RowCount只是指那个父结点有几个子。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. int rowCount(const QModelIndex &parent = QModelIndex()) const;  
  2. {  
  3. <pre name="code" class="cpp">if (! parent.isValid())  
  4.     {  
  5.         return 1;  
  6.     }  
  7.     else  
  8.     {  
  9.         RowNode *pNode = static_cast<RowNode *>(parent.internalPointer());  
  10.         if (pNode == m_child1)  
  11.         {  
  12.             return 1;  
  13.         }  
  14.         else  
  15.         {  
  16.             return 0;  
  17.         }  
  18.     }  

 

 

4)columnCount:用于设置列数,这个是整个TableView的列数。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. int columnCount(const QModelIndex &parent = QModelIndex()) const;  
  2. {  
  3.   return 4;  
  4. }  

 

 

5)headerData及setHeadData

 

[cpp] view plain copy
 
 技术分享技术分享
  1. QVariant headerData(int section, Qt::Orientation orientation,  
  2.                         int role = Qt::DisplayRole) const;  
  3. {  
  4. <pre name="code" class="cpp">    if (orientation == Qt::Vertical)  
  5.     {  
  6.         if (Qt::DisplayRole == role)  
  7.         {  
  8.             return "2";  
  9.         }  
  10.     }  
  11.     if (Qt::DisplayRole == role)  
  12.     {  
  13.         return "1";  
  14.     }  
  15.     else  
  16.         return QVariant();  

}
 bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
{
return true;
}

 

同data跟setData一样,但是是用于设置header的值,就是标题行及固定列的值。

 

6)index:用于设置返回的index的值。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. QModelIndex index(int row, int column,  
  2.                               const QModelIndex &parent = QModelIndex()) const;  
  3. {  
  4. <pre name="code" class="cpp">    if (! parent.isValid())  
  5.     {  
  6.         return createIndex(row, column, m_child1);  
  7.     }  
  8.     else  
  9.     {  
  10.         return createIndex(row, column, m_child2);  
  11.     }  

}

 

 

7)parent:用于设置父index。

 

[cpp] view plain copy
 
 技术分享技术分享
  1. QModelIndex parent(const QModelIndex &child) const;  
  2. {  
[cpp] view plain copy
 
 技术分享技术分享
  1.     RowNode *pRowNode = static_cast<RowNode *>(child.internalPointer());  
  2.     if (pRowNode == m_child2)  
  3.     {  
  4.         return createIndex(0, 0, m_child1);  
  5.     }  
  6.     return QModelIndex();  
  7. }  
技术分享

 

8)flags:用于返回model一些flags,如是否可以编辑的话,会加上Qt::itemIsEditable.

 

[cpp] view plain copy
 
 技术分享技术分享
  1. virtual Qt::ItemFlags flags(const QModelIndex &index) const;  
  2. {  
  3. <pre name="code" class="cpp">    Qt::ItemFlags oFlags = QAbstractItemModel::flags(index);  
  4.     return oFlags | Qt::ItemIsEditable;  
  5. }  

 

这样一个简单的model就实现了。

http://blog.csdn.net/hpjx1987/article/details/28005011

Qt中如何写一个model(自定义一个RowNode,我没有碰到过)