在 QML 中包含对象的 QAbstractListModel 有什么缺点?

What are the downsides of a QAbstractListModel containing objects in QML?

Qt 提供了将 C++ 模型与 QML 相结合的可能性 and suggests three approaches in the docs:

前两者使用起来非常简单,例如QObjectList:

// in C++
QList<QObject*> dataList;
dataList.append(new DataObject("Item 1", "red"));

// in QML
ListView {
    model: dataList
    delegate: Text { text: name }
}

但它们都带有强烈的警告:

Note: There is no way for the view to know that the contents of a QList has changed. If the QList changes, it is necessary to reset the model [...]

QAbstractItemModel 很难与对象一起使用,因为对象属性不会直接公开,因此要使它们保持同步需要付出很多努力。

但是,可以将 QList 包裹在 QAbstractItemModel 中并获得超级简单的模型。看这里:,


Qt 没有在本地实现这一点是有原因的吗?表现?内存管理问题?这似乎是一个明显的好主意,并且 ObjectModel 他们已经实现了类似的东西。

使用 QObject 作为模型项目的一个显着缺点是因为基础 class 相当大,它有点像 "god object"(这是反-pattern) 包含很多你在大多数时候并不真正需要的东西。因此,它在您可能拥有的任何模型数据之上有大约 160 个字节的 "overhead"。如果你有一个包含很多项目的大模型,而这些项目本身相对较小,这可能会有问题。你最终会有很多开销。

A QObjectList 作为模型总是一个坏主意,除非你正在做一些完全微不足道的事情。由于它没有实现适当的接口来通知引用视图的更改,唯一的方法是强制更新,每次都会重绘整个模型,而不仅仅是更改。

只要正确实现模型,项目对象是什么没有要求。

第二个实现特别有用,原因有很多:

  • 您无需为每个使用场景实施具有固定角色的特定 "static" 模型而烦恼
  • 您的模型项目可以具有根本不同的属性,您不限于模型 "schema"
  • 由于您正在处理 QObjectQ_PROPERTY
  • ,因此您会自动收到 QML 绑定的通知
  • 您可以声明式定义模型,甚至可以嵌套模型来创建树结构,这是 ListModel 做不到的。
  • 您可以在纯 QML 中定义实际模型项,而无需一直重新编译,a.k.a 快速原型制作,完成后,您可以简单地将对象移植到 C++
  • 同时,除了所有优点之外,该模型实际上比常规 "rigid" 模型更易于实施和维护,角色查找更快,因为您基本上只有一个 object 角色,没有任何查找,不需要为角色实现数据更改信号等等......简单易行