在Qt的ModelIndex中增加数据擦除

Model/View Framework

Qt中的QTableWidgetQListWidgetQTreeWidge等背后都是一套常见的Model/View架构用户分离显示和数据。一般的自定义View/Model都可以通过继承QAbstractItemViewQAbstractItemModel来快速实现。

ModelIndex

View/Model中通过ModelIndex来索引,ModelIndex中通过rowcolinternalPointer来索引到具体的数据。能够适配到绝大分数据结构。
但是也存在很大的问题,就在于internalPointer的类型是一个const void *,会丢失原有类型信息,这就要求internalPointer指向统一中数据结构。但是很多时候是无法把要显示的数据的数据结构都做成同一个虚基类(比如是修改不了的不同的外部连接库的类)。
通过传入类型擦除后的数据结构的指针,或者建立一个map表来索引internalPointer到具体的类型信息可以解决一部分问题,但是还有一些致命的问题————无法自动释放internalPointer指向类型擦除数据结构或者即使的清空map表,随着时间的迁移,内存占用会越来越庞大,或者引入了非常复杂的自动释放机制。

Solution

解决的办法很简单,将internalPointer的类型从const void *替换为QVariant等即可,以QVariant储存类型擦除后的数据结构,不需要修改任何逻辑。
不过这样则需要复制下QAbstractItemViewQAbstractItemModelModelIndex的源代码,重新构建下应用QVariantModelIndexModel/View框架。