我有一个QAbstractListModel
,其中存储了一堆自定义对象,您可以通过指定角色来访问模型中自定义对象的不同字段(如果这是对Qt角色的不当使用,请告诉我,因为我一定很困惑(。我想在用户友好的QTableView
中显示这些数据。我可以使用代理模型来显示内容,但问题是我不想显示原始值,我想显示从原始数据派生的特定数据。例如,我不希望ItemA.foo
和ItemA.bar
都有一列,我希望在一列中只显示ItemA.foo - ItemA.bar
。除此之外,我希望模型具有自动更新功能,如果ItemA.foo
或ItemA.bar
发生变化,我希望差异列自动更新并重新计算。
我认为这样做的方法是使用某种表代理模型,它侦听源模型,然后用从源模型派生的值填充自己的字段,并侦听来自源模型的dataChanged()
信号。然后将此代理模型插入到QTableView
中。但对我来说,这听起来像是应该在视图中做的事情。还是这是代表应该做的事情?我甚至可以在基本模型本身中进行这些计算,并添加特定于这些值的角色,这些值应该显示在表中,但这听起来像是我真的超载了模型的责任。
TLDR:如何在QTableView
中操作模型中的数据?我应该在基本模型中进行数据操作,然后将其发送到QTableView
吗?我应该使用一个代理模型来处理基本数据并将其发送到QTableView
吗?还是我完全误解了什么?
,您可以通过指定角色来访问模型中自定义对象的不同字段
如果您查看Qt::ItemDataRole的文档,您会发现Qt模型确实应该为不同的角色提供不同的数据,但每个角色都意味着与该角色对应的数据的一些不同用途。例如,最常用的角色可能是Qt::DisplayRole
,因为该角色的数据定义了视图中显示的内容,例如表单元格中的文本。如果您对视图的所有其他方面(字体、背景等(都满意,那么您只需为模型中的相应角色返回空的QVariant
,视图就会自己计算出这些细节。如果您使用角色作为列的替代品,即返回概念上相同数据项的不同部分,那么这可能不是角色的预期用途。
对于问题的另一部分,您可以通过使用委托自定义视图中显示的数据的外观。例如,您可以将QStyledItemDelegate
子类化,覆盖其displayText方法以显示ItemA.foo - ItemA.bar
而不仅仅是ItemA.foo
,然后通过setItemDelegateForColumn将此委托设置到视图中与ItemA.foo
对应的列中。这里棘手的部分是检测ItemA.foo
和ItemA.bar
列中的更改,这些更改会影响代理中显示的文本。不久前,我在我的一个项目中实现了一个专用的类,它可以监听原始模型的某个列中的更改;重新路由";通过信号发射改变为另一列。我这样做是为了解决这个问题——捕捉委托应该显示的内容的变化,尽管从技术上讲,没有设置委托的另一个模型列会受到影响。