基于单个数据源更新多个 Qt 模型
Update multiple Qt models based on a single data source
我想触发多个模型更新,从而基于原始数据源更新(如对象列表)触发多个视图更新。数据和多个模型之间的映射如何工作?
例如:
我有一个包含多个 Measurements
的列表,其中包含 size
、color
和 weight
等属性
- 一个模型被用作与
QListView
的界面,仅显示所有Measurements
中的size
- 一个模型用作带有
QTableView
的界面,显示所有测量的 size
和 color
- 等等
然后我触发对我的原始数据的更新。它可以来自上面提到的连接模型之一或来自外部更新。如何将此更改添加到我的所有关联模型中?
我在 Pyside2 中使用 python 但答案可以在 C++ 中
所以正如@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
修改模型和视图,您都可以从自动同步中获益
我想触发多个模型更新,从而基于原始数据源更新(如对象列表)触发多个视图更新。数据和多个模型之间的映射如何工作?
例如:
我有一个包含多个 Measurements
的列表,其中包含 size
、color
和 weight
- 一个模型被用作与
QListView
的界面,仅显示所有Measurements
中的 - 一个模型用作带有
QTableView
的界面,显示所有测量的size
和color
- 等等
size
然后我触发对我的原始数据的更新。它可以来自上面提到的连接模型之一或来自外部更新。如何将此更改添加到我的所有关联模型中?
我在 Pyside2 中使用 python 但答案可以在 C++ 中
所以正如@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