通常,有两种不同的方式在 C++/Qt/QML 模型/委托/视图架构中定义、创建和附加数据模型。让我们用表格视图示例来说明它们:
#1。 从 QAbstractItemModel 继承自己的 C++/Qt 类(或者从其专门的子类 QAbstractTableModel 对于我们的示例),定义自己的 C++/Qt/SQL/XML/JSON/etc 数据源/存储并重写/编写必要的 Qt建模虚拟方法以保护上行/下行数据流。然后在 QML 引擎启动时初始化 QML TableView 的 model 属性。
或
#2。使用 QML TableModel/TableModelColumn 定义自己的 QML 模型,用一些静态数据填充 QML TableModel rows 属性,或使用 QML TableModel 的数据操作方法附加/插入/删除一些动态数据。然后只需从 QML TableView 引用这样的 QML TableModel。
我的问题如下:
Q1:我可以调用 Qt QAbstractTableModel 的 data(index, role) 和 setData(index, value, role) 方法和 QML TableModel 的 data(index, role) 和 setData(index, value, role) ) 来自我的 QML JavaScript 代码的方法对于上述两个模型定义选项是否采用相同的方式?提示:经过大量测试后,我的印象是 QML JavaScript 中的 data()/setData() 仅适用于 QML TableModel,不适用于 Qt QAbstractTableModel ...
Q2:如果 Q1 的答案是“是”(我祈祷),那么 C++/Qt QVariant 将如何在 QML JavaScript 端进行转换/转换/处理? Qt QAbstractItemModel data()/setData() 将所有数据交换为 QVariants ...
感谢您的专业知识,这在 Qt/QML 文档中的描述方式非常令人困惑,或者更好地说,根本没有描述......
是的,QML 的
TableModel
方法的工作方式与自定义 QAbstractTableModel
类似。这是因为前者继承了后者。您可以在 Qt 源代码中找到 QML 的 TableModel
的源代码。 (对于 Qt 6,它位于 qtdeclarative/src/labs/models
、文件 qqmltablemodel_p.h
和 qqmltablemodel.cpp
中。相应的类在 C++ 中称为 QQmlTableModel
。)
实现自定义
QAbstractTableModel
不一定是一件容易的事情,特别是如果表格是可编辑的、单元格的或结构性的。然而,在实践中,走这条路是可行的,因为它还桥接了 QML GUI 和底层 C++ 业务逻辑。
我必须提到,您不应该直接致电
data
和 setData
。 Qt 模型系统具有“角色”的概念,它在 QML 代码中作为视图委托的属性公开。实现 QAbstractTableModel
时,配置特定模型的必要角色以及各种功能(包括单元格可编辑性)。通常,像
display
或 edit
这样的预定义角色就足够了。因此,使用预定义的 display
角色(C++ 中的 Qt::DisplayRole
)的只读模型可以在 QML 中像这样使用:
TableView {
// ...
delegate: Label {
text: display
}
}
在此设置中,QML 将为您调用带有
data
参数的 Qt::DisplayRole
。
分配 setData
属性时将调用 display
。当引用更深层嵌套的 QML 元素中的角色时,您可能需要限定该属性:
TableView {
// ...
delegate: Label {
id: delegateRoot
required property var model
text: delegateRoot.model.display
}
}
Qt 有一个用于模型编写的官方指南,不幸的是,您必须阅读大量指南才能创建功能性自定义模型。 Qt Creator 欢迎页面中提供的 Qt 教程和示例也很有帮助。
QVariant
转换在 QML 中是透明的。它确实支持JavaScript数组和对象,但我建议将自己限制在原始类型,因为它最终是一个UI模型,而不是业务逻辑模型。