基于单个数据源更新多个 Qt 模型
Posted
技术标签:
【中文标题】基于单个数据源更新多个 Qt 模型【英文标题】:Update multiple Qt models based on a single data source 【发布时间】:2020-07-23 07:37:18 【问题描述】:我想触发多个模型更新,从而根据原始数据源更新(如对象列表)触发多个视图更新。数据和多个模型之间的映射如何工作?
例如:
我有多个Measurements
的列表,其中包含size
、color
和weight
等属性
QListView
的接口,它仅显示所有Measurements
中的size
一个模型用作与QTableView
的接口,显示所有测量的size
和color
等
然后我触发对原始数据的更新。它可以来自上面提到的连接模型之一或来自外部更新。如何将此更改添加到我的所有关联模型?
我在 Pyside2 中使用 python,但答案可以是 C++
【问题讨论】:
我会考虑实现一个 QAbstractListModel 来提供所有数据(通过角色),然后使用简单的代理模型(QIdentityProxyModel 子类)将该数据映射到列/角色(主要是 Qt: :DisplayRole) 根据各个视图的需要。 听起来不错,我会研究这个方向,谢谢。您可以发表您的评论作为答案,如果它碰巧解决了这个问题,我会投赞成票并接受。 @Frank Osterfeld 我想我应该实现一个 QAbstractTableModel 来将不同的属性存储在不同的列中?或者 QAbstractListModel 是否能够使用角色来做到这一点? 这取决于用例。对于大多数 QML 应用程序,您将使用 QAbstractListModel 派生模型,但对于基于小部件的应用程序,使用多列更为常见。看到问题提到了 QTableView,我想说使用 QAbstractTableModel 作为基础是有意义的。然后,代理可以只是一个过滤掉一些列的 QSortFilterProxyModel。QStandardItemModel
通常是首选模型。然后在视图中决定应该显示哪些列。无需为抽象模型而烦恼。
【参考方案1】:
正如@Frank Osterfeld 在他的评论中所说,可以将您的所有数据存储在模型中(在我的情况下为QAbstractTableModel
),然后过滤掉您在各自视图中不需要的列。
为此,我使用了QSortFilterProxyModel
并覆盖了filterAcceptsColumn()
方法。
这是一个例子:
class MyModel(QAbstractTableModel):
def __init__(self):
super().__init__()
self.data = []
... # here are all the things you usually define in an abstract model
class MyProxyModelA(QSortFilterProxyModel):
def filterAcceptsColumn(self, source_column: int, source_parent: QModelIndex) -> bool:
""" This filters any column that returns true """
return source_column != 2
class MyProxyModelB(QSortFilterProxyModel):
def filterAcceptsColumn(self, source_column: int, source_parent: QModelIndex) -> bool:
""" This filters any column that returns true """
return source_column == 2
在我看来:
model = MyModel() # I put this here for the sake of this example
class MyWidgetA(QWidget):
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.table = QTableView()
self.proxy = MyProxyModelA()
self.proxy.setSourceModel(model)
self.table.setModel(self.proxy)
self.ui.layout.addWidget(self.table)
class MyWidgetB(QWidget):
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.table = QTableView()
self.proxy = MyProxyModelB()
self.proxy.setSourceModel(model)
self.table.setModel(self.proxy)
self.ui.layout.addWidget(self.table)
现在,您可以在通过MyWidgetA
或MyWidgetB
修改模型和视图时自动同步您的模型和视图
【讨论】:
以上是关于基于单个数据源更新多个 Qt 模型的主要内容,如果未能解决你的问题,请参考以下文章
C#开发BIMFACE系列24 服务端API之获取模型数据9:获取单个房间信息