Qt 文档对模型/ View 框架做了很多介绍,但它似乎只支持从 QAbstractItemModel
继承的模型 - 即表、列表和树之类的东西。其他类型的模型怎么样(如 MVC 模式的一般概念)?
在我的具体情况下,用户正在输入生物信息学工具的输入和参数。在 JSON 中,我想要的数据可能如下所示:
{
"files": [
{
"path": "/path/to/file1.fasta",
"format": "fasta",
"compression": null
},
{
"path": "/path/to/file2.fastq",
"format": "fastq",
"compression": "gzip"
},
...
],
"taxonomy_database_id": 1,
"reference_signatures_set": "my_signatures_set",
"results_per_file": 5,
...
}
files
属性非常适合 Qt 的模型系统 - 我使用某种具有三列的 QAbstractTableModel
,创建一个 QTableView
来查看它,然后添加一个显示 QFileDialog
的按钮,其中包含一些向其中添加行的逻辑。
其余属性不太适合 Qt 模型框架。它们没有顺序,值是非同质的,我需要能够通过名称访问它们。该模型只有一个实例,因此没有太多理由像我对文件所做的那样将其粘贴到表中。
我的确切模型没有什么特别之处,这与用户输入个人信息时遇到的问题相同:
{
"name": "John Doe",
"age": 25,
"zip_code": 12345,
}
在我的情况和示例中,我可能想要连接到通知我更改的信号,然后运行一些验证逻辑。然而,这些不仅仅是通用的“项目”,每一项都有特定的逻辑 - 例如检查邮政编码以查看用户是否在服务范围内或检查用户是否是未成年人。代码检查 model.getZipCode()
的返回值比检查 model.data(model.index(2, 0))
更有意义。
通过子类化 QObject
并将所有属性实现为 Qt 属性,可以轻松实现数据存储和业务逻辑。然而,为此建立观点变得很痛苦。 Qt 似乎没有任何内置的 View 类。我可以创建一个表单小部件进行编辑,没有太大问题,但对象属性和 QComboBox 等之间的双向数据绑定(bind)很难开箱即用。
如果我将模型实现为具有一列和行属性的 QAbstractItemModel
,我可以非常轻松地创建 View 和编辑器。使用 QDataWidgetMapper
连接到我的表单中的编辑器小部件特别容易。当用户编辑小部件时模型会更新,当我将模型重置为默认值或加载保存的配置时 View 也会更新。但为了使用这个模型,我必须使用 QModelIndex 以及行和列来处理所有内容,这对于模型的实际语义来说是没有意义的。这使得业务逻辑变得更加困难和困惑。
我提出的解决方案只是一个位于真实模型和 View 之间的代理QAbstractListModel
,但这似乎不必要地复杂。这就是为什么我感到困惑,感觉我错过了文档或示例中的一些主要内容。
最佳答案
似乎您在这里混淆了一些概念。
Qt 模型 View 依赖于
QAbstractItemModel
,因为它们需要接口(interface)来访问模型数据。他们根本无法使用不提供此接口(interface)的QObject
。附加提示:
QAbstractItemModel
派生自QObject
。-
just a set of named fields or key-value pairs
事实上,这是一个列表或表结构,具体取决于您是否有一列或(至少)两列。您期望“其他类型的模型”是什么样子?
- 对于简单模型,您可以从
QAbstractListModel
或QAbstractTableModel
派生,甚至可以使用QStringListModel
或QStandardItemModel
;前两者包含大部分,后者包含为这些标准情况实现的所有抽象方法。 -
The model itself is easy enough to create as a QObject with some properties.
如果您出于某种原因认为这是一种可行的方法,那么您可以自行决定是否实现一个使用
QObject
数据属性的模型。但在大多数情况下,这是不必要的间接层,IMO。
关于python - 在 QT4/PySide 中编辑不是基于树/表/列表的模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45645195/