在 QML 中包含对象的 QAbstractListModel 有什么缺点?
What are the downsides of a QAbstractListModel containing objects in QML?
Qt 提供了将 C++ 模型与 QML 相结合的可能性 and suggests three approaches in the docs:
QStringList
QObjectList
QAbstractItemModel
前两者使用起来非常简单,例如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"
- 由于您正在处理
QObject
和 Q_PROPERTY
,因此您会自动收到 QML 绑定的通知
- 您可以声明式定义模型,甚至可以嵌套模型来创建树结构,这是
ListModel
做不到的。
- 您可以在纯 QML 中定义实际模型项,而无需一直重新编译,a.k.a 快速原型制作,完成后,您可以简单地将对象移植到 C++
- 同时,除了所有优点之外,该模型实际上比常规 "rigid" 模型更易于实施和维护,角色查找更快,因为您基本上只有一个
object
角色,没有任何查找,不需要为角色实现数据更改信号等等......简单易行
Qt 提供了将 C++ 模型与 QML 相结合的可能性 and suggests three approaches in the docs:
QStringList
QObjectList
QAbstractItemModel
前两者使用起来非常简单,例如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"
- 由于您正在处理
QObject
和Q_PROPERTY
,因此您会自动收到 QML 绑定的通知
- 您可以声明式定义模型,甚至可以嵌套模型来创建树结构,这是
ListModel
做不到的。 - 您可以在纯 QML 中定义实际模型项,而无需一直重新编译,a.k.a 快速原型制作,完成后,您可以简单地将对象移植到 C++
- 同时,除了所有优点之外,该模型实际上比常规 "rigid" 模型更易于实施和维护,角色查找更快,因为您基本上只有一个
object
角色,没有任何查找,不需要为角色实现数据更改信号等等......简单易行