c++ - 包含 QML 中的对象的 QAbstractListModel 有哪些缺点?

标签 c++ qt qml qabstractitemmodel

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 的更改,唯一的方法是强制更新,这将每次重新绘制整个模型而不仅仅是更改。

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

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

  • 您无需为每个使用场景实现具有固定角色的特定“静态”模型
  • 您的模型项可以具有根本不同的属性,您不限于模型“架构”
  • 由于您正在处理 QObjectQ_PROPERTY,因此您会自动收到 QML 中的绑定(bind)通知
  • 您可以以声明式方式定义模型,甚至可以嵌套模型来创建树结构,这是 ListModel 无法做到的。
  • 您可以在纯 QML 中定义实际的模型项,而无需一直重新编译,即快速原型(prototype)设计,完成后,您可以简单地将对象移植到 C++
  • 同时,除了所有优点之外,该模型实际上比常规“刚性”模型更容易实现和维护,角色查找速度更快,因为您本质上只有一个对象 角色并且无需任何查找,无需为角色等实现数据更改信号...简单

关于c++ - 包含 QML 中的对象的 QAbstractListModel 有哪些缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43809751/

相关文章:

c++ - C++ 中的枚举

c++ - 错误: …protected functions

c++ - 水平排列 QMenu 项目

android - qt qml : deploying sqlite database to android using . qrc 文件不工作

python - 是否有等同于wx.FutureCall(在窗口初始化和绘制后调用函数)的PyQT?

qt - 从委托(delegate)访问 ListView currentIndex

javascript - 从 QML 中的数组中的 bool 更改颜色

c++ - macport 使用哪个编译器?

c++ - 当需要数组时,将指针传递给 vector 中的第一个元素是否安全?

c++ - 从 qml 访问 Qt 2 或 3d bool 列表