这里指出3种方式的比较,说是3中编程架构也行,其实不仅仅针对tree显示结构,对table,list等同样适用。

  1. 直接用qtreewidget,使用例子​​qtreeview和qtreewidget[ansys简单示例]-Java架构师必看​
  2. 用模型/视图,用qt提供的标准QstandItemModel,可以看我这篇博客:
  3. 用模型/视图,子类化QAbstractItemModel方式

先讲结论:

结论

qtreewidget用于数据简单,数据项少,解耦程度要求低的场合。但是代码非常简单。

其它情况,用qtreeview这种模型/视图框架。如果想用自己的数据结构体管理方式,那么用模型/试图中的子类化QAbstractItemModel方式,否则用qt提供的标准QstandItemModel 就行,代码简单很多。

qtreeview和qtreewidget的区别 使用总结 和选择_子类

注:用标准模型QstandItemModel,就不能用自己的结构体作为item,因为自己的结构体没有appendRow()等函数来自动的创建出索引关系来。子类化的QAbstractItemModel也不能用标准的QStandardItem,因为此时的模型没有appendRow()等函数来添加这些item。所以,上面说的两种模型视图使用方式才是正确的。

qtreeview的使用

需要先有一个model,然后qtreeview->setModel(model)即可,具体的后续显示啥的,就不用我们管了。

模型能存数据

模型是代表结构体数据之间的组织关系,里面会有父子关系什么的,模型是一个类啊,就是我们自己的东西了,我们可以在里面定义私有变量,比如要显示的大量数据,都放这里面。

要不要子类化QAbstractItemModel来用

QStandardItemModel是qt提供了的,就是子类化的QAbstractItemModel。而我们使用的话,不再子类化QStandardItemModel,而是子类化QAbstractItemModel。

子类化的话,需要重写里面很多虚函数,目的是告诉模型你如何提供这些项目的索引,也就是提供它们的位置关系,这样treeView在显示时候会调这些函数,才能显示出来

子类化QAbstractItemModel的情况(对应图中的方式2)

看看你是否提前已经有一个多叉树这样的数据结构了(比如struct People构成的)。如果有,用这个就还可以,因为重写parent(),rowCount(),data()等函数,我们遍历我们已有的多叉树数据结构,就能返回对应的值了。我们重写这些函数,实际上就是映射我们的多叉树数据结构到模型了,那我们后续只要修改我们这个多叉树数据结构,调用模型的xxUpdate函数就能自动更新了,比如

mModel.beginUpdate();   

xxx(我们对我们的数据结构的修改,比如增加谁谁的孩子,删除谁谁谁。)

mModel.endUpdate();

注:模型中是以QModelIndex作为索引的(这玩意其实就是“项”的首地址),和QStandardItem没有关系,此时我们的每个struct People就是这里面的item的作用。(在我的图中举的例,就是Struct Node作为item)

所以如果提前有这么个数据结构了的,这样用还是挺方便的,这样解耦得更彻底(不仅模型和视图解耦了,数据和模型也解耦了)。实现自己管理自己的熟悉的数据结构方式

但是如果提前没有这么一个数据结构,那完全没必要了,因为让你重写parent(),rowCount()这些函数,你能知道一个节点的父节点是谁吗,你能知道他有多少孩子吗,这是不知道的。这时候用qt提供的标准QstandItemModel,节点用QstandItem就行(每个QstandItem项item除了能指定文本,图标啥的信息,还能用item->setData(),直接把一个复合数据(比如QMap等)给存进去。)即可。

当然,提前有了这个数据结构,你也可以不子类化QAbstractItemModel,那就就用QStandardItem作为item,然后遍历数据结构,对应创建出这些item也是可以的。但是当我们的数据结构发生改变(比如增加谁谁的孩子,删除谁谁谁),此时我们还得去找到它对应的item,让它修改还是删除啥的,明显比上面的子类化方式(图中的方式2)麻烦了。

qtreewidget的使用

这个跟简单了,直接创建一些项item就行了(指定名称图标啥的),然后窗口会自动更新了。所以这里没有模型model的概念。

qtreeview和qtreewidget的优缺点和选择

qtreewidget

使用简单,直观,代码简洁,仅仅做一些显示,简单操作,就用这个。每个item就代表一个子widget,所以item数目非常多的时候,吃内存和性能。而且界面直接可以编辑。所以简单的展示场景,就用这个。

qtreeview

  • 代码复杂一点儿,但是有model,这个可以存数据,model里面的item就自己能构成多叉树结构。
  • item数量特别多的时候,不吃性能。
  • model可以再次去映射到其他view上去,从而实现快速视图切换。
  • model可以用QStyledItemDelegate这个代理类,从而自己定制item的绘制过程,可以实现炫酷的展示效果。这个是qtreewidget不能具备的。