QT Tree model
2014-08-27 18:10
176 查看
Qt 的确是一个好东西,开发起来非常方便,但是方便也带来很多问题,这些问题就不多说了,用到的人自然会有体会。
这几天在研究Qt的MVC,List和Table类型的都很简单,没有什么难度,但是它的TreeModel实在是让我晕了好几天。
一般用TreeModel都是用自己的类,于是,按着文档上说明的,关于继承QAbstractItemModel的时候,必须实现如下几个函数:index(), parent(), rowCount(), columnCount(), data(), 要让Model变成可以编辑的话,必须还要实现 setData(), flags() 这两个函数,让flags()返回值有ItemIsEditable。 同时,还可以实现headerData()和 setHeaderData()
来控制View中的标题。
接下来的问题就简单一些,实现它的数据结构,结构也很简单,就是简单的树形,一行,就是一个数据(当然,这一行也可以是很多数据),这里一行,就是一个item,每个里面的数据就是对应的column。在实现上,这个item可以有list,含有它的child, 也要有一个parent的指针。最Root,只有一个node(记得,我们说的是Tree!) , 简单吧? 如果要把这样的结构与其它scene graph一起用,基本上不用实现那个list和parent的指针,因为SG的node会给你这样的信息。
下面的问题,就是实现那几个必须的函数。
QModelIndex index ( int row, int column, const QModelIndex & parent ) const
这个函数对View来说,就是要你给它它所需要的行与列上的index.不管这个item有没有parent,view都会给你一个parent,当然,如果没有parent,那这个parent的index就是无效的。来看看怎么实现
上面,if(parent.isValid()==false),如果view给出的parent无效,那当前所指的item一定是第一层,也就是Root下面的。如果不是,那就用parentItem=static_cast(parent.internalPointer()) 得到这个node的指针,然后,看这个node里view需要的那一行上是否有node,如果没有,就返回无效的index(
return QModelIndex())。
QModelIndex parent ( const QModelIndex & index ) const
这个函数,是view向你要一个指定index的parent的index.来看看怎么实现
如果view给我一个无效的index,那我当然告诉它,这个无效的index的parent也是无效的,无效的parent,在这里,就是明确说明这个index是顶层的node的index,无效的含义只有这一个。代码很简单,得到这个index所指node的指针,看它有没有parent,如果它的parent就是root,那就也返回一个无效的index,否则就create一个,返回给view.
5个必须实现的函数中,只有这两个是要返回index的,在createIndex中,parent函数的index中列的数量好象不重要,我把它随便设一个数,结果都是正确的,也可能是因为,我的结构就是这样,列上的东西,就是数据,而不是node,node都是行。在createIndex中,可以包含一个指针,或一个int,这里,我要它在每个index中,都直接有一个node的指针,这对于其它的函数,是非常方便的 int
rowCount ( const QModelIndex & parent ) const
这个函数简单,每个index中都有一个指针,我拿到这个指针,看它指向的node有几个child,然后返回这个数,就OK了。如果index无效,那这个index就是root。看代码
int columnCount(const QModelIndex &parent ) const
一个node有几个数据,返回就是了,没什么好说的
QVariant
data(const QModelIndex &index, int role ) const
这个data,可不要什么role都返回一个数据,那样,就是全空,这个问题搞了我一天,最后才突然发现是这里有问题。
最后看一下CTreeItem的代码:
这几天在研究Qt的MVC,List和Table类型的都很简单,没有什么难度,但是它的TreeModel实在是让我晕了好几天。
一般用TreeModel都是用自己的类,于是,按着文档上说明的,关于继承QAbstractItemModel的时候,必须实现如下几个函数:index(), parent(), rowCount(), columnCount(), data(), 要让Model变成可以编辑的话,必须还要实现 setData(), flags() 这两个函数,让flags()返回值有ItemIsEditable。 同时,还可以实现headerData()和 setHeaderData()
来控制View中的标题。
接下来的问题就简单一些,实现它的数据结构,结构也很简单,就是简单的树形,一行,就是一个数据(当然,这一行也可以是很多数据),这里一行,就是一个item,每个里面的数据就是对应的column。在实现上,这个item可以有list,含有它的child, 也要有一个parent的指针。最Root,只有一个node(记得,我们说的是Tree!) , 简单吧? 如果要把这样的结构与其它scene graph一起用,基本上不用实现那个list和parent的指针,因为SG的node会给你这样的信息。
下面的问题,就是实现那几个必须的函数。
QModelIndex index ( int row, int column, const QModelIndex & parent ) const
这个函数对View来说,就是要你给它它所需要的行与列上的index.不管这个item有没有parent,view都会给你一个parent,当然,如果没有parent,那这个parent的index就是无效的。来看看怎么实现
CTreeItem *parentItem; if(parent.isValid()==false) parentItem=m_pRootItem; else parentItem=static_cast(parent.internalPointer());
CTreeItem *childItem = parentItem->child(row); if(childItem) return createIndex(row,column,childItem); else return QModelIndex();
上面,if(parent.isValid()==false),如果view给出的parent无效,那当前所指的item一定是第一层,也就是Root下面的。如果不是,那就用parentItem=static_cast(parent.internalPointer()) 得到这个node的指针,然后,看这个node里view需要的那一行上是否有node,如果没有,就返回无效的index(
return QModelIndex())。
QModelIndex parent ( const QModelIndex & index ) const
这个函数,是view向你要一个指定index的parent的index.来看看怎么实现
if(index.isValid()){ CTreeItem * childItem=static_cast(index.internalPointer()); CTreeItem * parentItem=childItem->parent();
if(parentItem==m_pRootItem) return QModelIndex(); else return createIndex(parentItem->row(),20,parentItem); } else return QModelIndex();
如果view给我一个无效的index,那我当然告诉它,这个无效的index的parent也是无效的,无效的parent,在这里,就是明确说明这个index是顶层的node的index,无效的含义只有这一个。代码很简单,得到这个index所指node的指针,看它有没有parent,如果它的parent就是root,那就也返回一个无效的index,否则就create一个,返回给view.
5个必须实现的函数中,只有这两个是要返回index的,在createIndex中,parent函数的index中列的数量好象不重要,我把它随便设一个数,结果都是正确的,也可能是因为,我的结构就是这样,列上的东西,就是数据,而不是node,node都是行。在createIndex中,可以包含一个指针,或一个int,这里,我要它在每个index中,都直接有一个node的指针,这对于其它的函数,是非常方便的 int
rowCount ( const QModelIndex & parent ) const
这个函数简单,每个index中都有一个指针,我拿到这个指针,看它指向的node有几个child,然后返回这个数,就OK了。如果index无效,那这个index就是root。看代码
CTreeItem *parentItem; if(parent.isValid()) parentItem=static_cast(parent.internalPointer()); else parentItem=m_pRootItem; return parentItem->childCount();
int columnCount(const QModelIndex &parent ) const
一个node有几个数据,返回就是了,没什么好说的
QVariant
data(const QModelIndex &index, int role ) const
if(index.isValid()==false) return QVariant(); if(role != Qt::DisplayRole) return QVariant(); CTreeItem *item=static_cast(index.internalPointer()); return item->data(index.column());
这个data,可不要什么role都返回一个数据,那样,就是全空,这个问题搞了我一天,最后才突然发现是这里有问题。
最后看一下CTreeItem的代码:
class CTreeItem { public: CTreeItem(QStringList data,CTreeItem *parent=0); ~CTreeItem(void); void appendChild(CTreeItem *child); CTreeItem *child(int row); int childCount() const; int columnCount() const; QVariant data(int column) const; int row() const; CTreeItem * parent(); private: QStringList m_StrData; QList m_Children; CTreeItem * m_pParent; }; CTreeItem::CTreeItem(QStringList data,CTreeItem *parent) :m_pParent(parent),m_StrData(data) { m_Children.clear(); } CTreeItem::~CTreeItem(void) { qDeleteAll(m_Children); } void CTreeItem::appendChild(CTreeItem *child) { m_Children.append(child); } int CTreeItem::childCount() const { return m_Children.size(); } int CTreeItem::columnCount() const { return m_StrData.size(); } QVariant CTreeItem::data(int column) const { return m_StrData.value(column,”"); } int CTreeItem::row() const { if(m_pParent) return m_pParent->m_Children.indexOf(const_cast(this)); else return 0; } CTreeItem * CTreeItem::parent() { return m_pParent; } CTreeItem * CTreeItem::child(int row) { return m_Children.value(row); }
相关文章推荐
- Qt:在TreeModel+QTreeView中使用复选框(checkbox)
- Qt:在TreeModel+QTreeView中使用复选框(checkbox)
- QT学习2:Table/List/Tree的View,Widget,Model相关
- Qt:在TreeModel+QTreeView中使用复选框(checkbox)
- Qt:TreeModel+QTreeView中使用图标
- Qt:在TreeModel+QTreeView中使用复选框问题
- Qt:TreeModel+QTreeView中使用图标
- Qt:在TreeModel+QTreeView中使用复选框(checkbox)
- Undo/Redo for Qt Tree Model
- Qt Model/View 学习笔记
- qt model中headerData()函数的调用
- QT学习——数据库SQL模型类(QSqlTableModel模型)
- Qt Model/View 学习笔记 (七)
- Qt之QTableView添加复选框(QAbstractTableModel)
- Qt Model/View( 一)
- Qt数据库:(七)QSqlRelationalTableModel
- QT model/view 详细资料 总结
- Qt Model/View 学习笔记(七)
- QT QSqlQuery QSqlQueryModel
- Qt 常用部件 (五) Model/View