• Qt中如何写一个model


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

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

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    1. int columnCount(const QModelIndex &parent = QModelIndex()) const;  
    2. {  
    3.   return 4;  
    4. }  

    5)headerData及setHeadData

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    1. QModelIndex parent(const QModelIndex &child) const;  
    2. {  
    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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
     
     在CODE上查看代码片派生到我的代码片
    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

  • 相关阅读:
    测试文档
    详细文档
    需求规格说明文档
    会议
    软工项目
    分组
    项目名
    google 常用的搜索关键词 (技术相关)
    Kafka 入门和 Spring Boot 集成
    用nginx实现分布式限流
  • 原文地址:https://www.cnblogs.com/findumars/p/5995210.html
Copyright © 2020-2023  润新知