Qt中如何写一个model

来源:互联网 发布:嵌入式需要mac 编辑:程序博客网 时间:2024/06/05 01:57

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

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

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);int rowCount(const QModelIndex &parent = QModelIndex()) const;int columnCount(const QModelIndex &parent = QModelIndex()) const<pre name="code" class="cpp">QVariant headerData(int section, Qt::Orientation orientation,                        int role = Qt::DisplayRole) const;bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,                       int role = Qt::EditRole);QModelIndex index(int row, int column,                              const QModelIndex &parent = QModelIndex()) const;QModelIndex parent(const QModelIndex &child) const;virtual Qt::ItemFlags flags(const QModelIndex &index) const;

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

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

class RowNode{public:    RowNode() { m_pNode = NULL; }    ~RowNode() {}public:    inline void setParent(RowNode *rowNode) { m_pNode = rowNode; }    inline RowNode *parent() { return m_pNode; }private:    RowNode *m_pNode;};

model构造里

    m_child1 = new RowNode();    m_child2 = new RowNode();    m_child2->setParent(m_child1);

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

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;{<pre name="code" class="cpp">if (Qt::DisplayRole == role)    {        RowNode *pRowNode = static_cast<RowNode *>(index.internalPointer());        if (m_child1 == pRowNode)        {            if (0 == index.column())            {                return "Test";            }            else if (1 == index.column())            {                return "Icon";            }            else if (2 == index.column())            {                return "comboBox";            }        }        else        {            if (0 == index.column())            {                return "col0";            }            else if (1 == index.column())            {                return "col1";            }            else            {                return "col2";            }        }    }    else        return QVariant();}

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

bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);{  return true;}

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

int rowCount(const QModelIndex &parent = QModelIndex()) const;{<pre name="code" class="cpp">if (! parent.isValid())    {        return 1;    }    else    {        RowNode *pNode = static_cast<RowNode *>(parent.internalPointer());        if (pNode == m_child1)        {            return 1;        }        else        {            return 0;        }    }

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

int columnCount(const QModelIndex &parent = QModelIndex()) const;{  return 4;}

5)headerData及setHeadData

QVariant headerData(int section, Qt::Orientation orientation,                        int role = Qt::DisplayRole) const;{<pre name="code" class="cpp">    if (orientation == Qt::Vertical)    {        if (Qt::DisplayRole == role)        {            return "2";        }    }    if (Qt::DisplayRole == role)    {        return "1";    }    else        return QVariant();
}
 bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
{
return true;
}

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

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

QModelIndex index(int row, int column,                              const QModelIndex &parent = QModelIndex()) const;{<pre name="code" class="cpp">    if (! parent.isValid())    {        return createIndex(row, column, m_child1);    }    else    {        return createIndex(row, column, m_child2);    }
}

7)parent:用于设置父index。

QModelIndex parent(const QModelIndex &child) const;{
    RowNode *pRowNode = static_cast<RowNode *>(child.internalPointer());    if (pRowNode == m_child2)    {        return createIndex(0, 0, m_child1);    }    return QModelIndex();}

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

virtual Qt::ItemFlags flags(const QModelIndex &index) const;{<pre name="code" class="cpp">    Qt::ItemFlags oFlags = QAbstractItemModel::flags(index);    return oFlags | Qt::ItemIsEditable;}

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

0 0
原创粉丝点击