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
中并获得 super 简单的模型。参见这里:Implementation 1 , Implementation 2
Qt 没有原生实现这个功能有什么原因吗?表现?内存管理问题?这似乎是一个明显的好主意,并且 ObjectModel
他们已经实现了类似的东西。
最佳答案
使用QObject
作为模型项的一个显着缺点是因为基类非常大,它是一种“上帝对象”(这是一种反模式),包含很多你大多数时候并不真正需要的东西。因此,除了您可能拥有的任何模型数据之外,它还有大约 160 字节的“开销”。如果您有一个包含大量元素的大模型,并且元素本身相对较小,这可能会出现问题。您最终会产生大量开销。
将QObjectList
作为模型始终是一个坏主意,除非您正在做一些完全微不足道的事情。由于它没有实现适当的接口(interface)来通知引用 View 的更改,唯一的方法是强制更新,这将每次重新绘制整个模型而不仅仅是更改。
对项目对象是什么没有要求,只要正确实现模型即可。
第二个实现特别有用,原因有很多:
- 您无需为每个使用场景实现具有固定角色的特定“静态”模型
- 您的模型项可以具有根本不同的属性,您不限于模型“架构”
- 由于您正在处理
QObject
和Q_PROPERTY
,因此您会自动收到 QML 中的绑定(bind)通知 - 您可以以声明式方式定义模型,甚至可以嵌套模型来创建树结构,这是
ListModel
无法做到的。 - 您可以在纯 QML 中定义实际的模型项,而无需一直重新编译,即快速原型(prototype)设计,完成后,您可以简单地将对象移植到 C++
- 同时,除了所有优点之外,该模型实际上比常规“刚性”模型更容易实现和维护,角色查找速度更快,因为您本质上只有一个
对象
角色并且无需任何查找,无需为角色等实现数据更改信号...简单
关于c++ - 包含 QML 中的对象的 QAbstractListModel 有哪些缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43809751/