作者:一个程序渣渣的小后院 地址:http://blog.youkuaiyun.com/sinat_35261315/article/details/54849486
Model/View Framework中提供了模型model的抽象基类QAbstractItemModel, 如果需要自定义模型就需要继承这个类并且实现一些必要的函数。
此外,Qt中又提供了QAbstractTableModel和QAbstractListModel分别继承于上述基类,由名字可以清楚的知道这两个类分别适用于表格模型和列表模型。对于这两个模型来说,很多函数已经重新实现过了,使用时直接继承即可。
QAbstractItemModel
QAbstractItemModel为元素模型类提供了抽象接口,自定义模型时需要继承这个类。自定义的模型分为只读模型和可编辑模型。
只读模型:内部数据不能修改
为了实现一个只读模型,需要重新实现以下函数:
flags
- 1
- 1
这个函数返回被给模型索引index的标志,用于其他组件获得每一个元素的信息。在很多模型中,返回的flags应该包括Qt::ItemIsEnabled和Qt::ItemIsSelectable,表示模型中的元素是可以被访问和选择的。通常实现的形式为:
- 1
- 2
- 3
- 1
- 2
- 3
data
- 1
- 1
这个函数返回模型索引index的底层数据(一个模型索引包括某一元素的信息,包括行,列,以及数据),用于视图和委托访问数据。通常的实现形式如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
headerData
- 1
- 1
这个函数返回某部分对应方向上的表头,为Views提供显示在Views顶部(即最上方和最左边)的标识。通常实现形式为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
rowCount
- 1
- 1
这个函数返回被给的模型索引下有多少行,返回的是parent的孩子数。而不是整个行数。如果没有子元素,则返回0。
对于继承于QAbstractListModel的类来说,只需要重新实现这四个函数。而对于继承于QAbstractTableModel和QAbstractItemModel的类来说,除了上述四个函数,还需要重新实现columnCount函数,因为列表只有1列,而表格和树则需要自定义:
columnCount
- 1
- 1
这个函数通常与给定的parent无关,所涉及的类有几列就返回几。
可编辑模型:允许数据被修改,也可以允许插入和删除操作。
实现可编辑模型,除了上述只读模型的函数外,还需要重新实现以下函数:
flags
- 1
- 1
这个函数和只读模型的函数一样,只是返回时需要增加Qt::ItemIsEditable,形式如下:
- 1
- 2
- 3
- 1
- 2
- 3
setData
- 1
- 1
data函数用来获取数据,setData函数用来设置模型索引index中存储的数据,形式如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
另外需要注意的是,在改变完内部数据后,需要发出dataChanged(index, index)信号通知Views和Delegate内部数据已经发生改变。
setHeaderData
- 1
- 1
headerData函数用于返回表头,这个函数设置表头为value,形式如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
同样,当改变表头后,需要发出headerDataChanged(orientation, section, section)信号,通知Views和Delegate。
如果需要添加和删除操作,则需要实现以下函数:
insertRows
- 1
- 1
这个函数在父级为index的结构中的第position行插入rows行。形式如下:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
进行插入操作时,前后分别需要调用beginInsertRows()和endInsertRows()函数。
removeRows
- 1
- 1
这个函数在父级为index的结构中的第position行删除rows行。形式如下:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
进行删除操作时,前后需要调用beginRemoveRows()和endRemoveRows()函数。
insertColumns
removeColumns
这两个函数同插入行和删除行类似,也需要调用两个函数。
通常情况下,函数应该返回true如果操作成功,但是如果只是部分操作成功,例如只插入了部分行,则需要返回false。
例子:http://qimo601.iteye.com/blog/1534331