为什么 layoutChanged.emit() 在使用 QSortFilterProxyModel 时不更新 QListView?
Why does layoutChanged.emit() not update the QListView when using a QSortFilterProxyModel?
我无法让 QListView 使用代理模型。
我开始将 QListViews 与模型一起使用,没有任何问题,并在运行时使用该模型的 datachanged.emit() 信号更改数据。
但是,当我尝试更改基于代理模型的 QListView 中的数据时,该数据未在界面中更新。
我把它归结为一个最小的例子,但仍然看不出这种行为的根本原因:
from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QApplication, QListView)
from PyQt5 import QtCore
# model for QListView
class ListModel(QtCore.QAbstractListModel):
def __init__(self, items):
super().__init__()
self.items = items
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return self.items[index.row()]
def rowCount(self, index):
return len(self.items)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# creating list with "standard" model and an initial dataset => this works
list_view_1 = QListView()
list_view_1.setModel(ListModel(['original', 'model']))
# creating list with proxy based on source model and an initial dataset => this works
list_view_2 = QListView()
proxy = QtCore.QSortFilterProxyModel()
proxy.setSourceModel(ListModel(['original', 'proxy+model']))
list_view_2.setModel(proxy)
# changing data in model and emitting layout change => this works
list_view_1.model().items = ['changed', 'model']
list_view_1.model().layoutChanged.emit()
# changing data in proxy and emitting layout change => this does not work?
list_view_2.model().items = ['changed', 'proxy+model']
list_view_2.model().layoutChanged.emit()
# adding layout to the interface
hbox = QHBoxLayout()
hbox.addWidget(list_view_1)
hbox.addWidget(list_view_2)
self.setLayout(hbox)
self.show()
app = QApplication([])
window = MainWindow()
app.exec_()
None 我的搜索导致了对这种行为的解释,a related stack thread 只提到了模型的顺序,我已经用这种方式实现了。
谁能告诉我如何正确更新“代理模型”中的数据的解决方案?
问题是您在代理模型中创建属性(项目)而不是更新源模型项目,解决方案是更新源模型项目:
# ...
# changing data in model and emitting layout change => this works
list_view_1.model().items = ["changed", "model"]
list_view_1.model().layoutChanged.emit()
# changing data in proxy and emitting layout change => this does not work?
list_view_2.model().<b>sourceModel()</b>.items = ["changed", "proxy+model"]
list_view_2.model().layoutChanged.emit()
# ...
我无法让 QListView 使用代理模型。
我开始将 QListViews 与模型一起使用,没有任何问题,并在运行时使用该模型的 datachanged.emit() 信号更改数据。
但是,当我尝试更改基于代理模型的 QListView 中的数据时,该数据未在界面中更新。
我把它归结为一个最小的例子,但仍然看不出这种行为的根本原因:
from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QApplication, QListView)
from PyQt5 import QtCore
# model for QListView
class ListModel(QtCore.QAbstractListModel):
def __init__(self, items):
super().__init__()
self.items = items
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return self.items[index.row()]
def rowCount(self, index):
return len(self.items)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# creating list with "standard" model and an initial dataset => this works
list_view_1 = QListView()
list_view_1.setModel(ListModel(['original', 'model']))
# creating list with proxy based on source model and an initial dataset => this works
list_view_2 = QListView()
proxy = QtCore.QSortFilterProxyModel()
proxy.setSourceModel(ListModel(['original', 'proxy+model']))
list_view_2.setModel(proxy)
# changing data in model and emitting layout change => this works
list_view_1.model().items = ['changed', 'model']
list_view_1.model().layoutChanged.emit()
# changing data in proxy and emitting layout change => this does not work?
list_view_2.model().items = ['changed', 'proxy+model']
list_view_2.model().layoutChanged.emit()
# adding layout to the interface
hbox = QHBoxLayout()
hbox.addWidget(list_view_1)
hbox.addWidget(list_view_2)
self.setLayout(hbox)
self.show()
app = QApplication([])
window = MainWindow()
app.exec_()
None 我的搜索导致了对这种行为的解释,a related stack thread 只提到了模型的顺序,我已经用这种方式实现了。
谁能告诉我如何正确更新“代理模型”中的数据的解决方案?
问题是您在代理模型中创建属性(项目)而不是更新源模型项目,解决方案是更新源模型项目:
# ...
# changing data in model and emitting layout change => this works
list_view_1.model().items = ["changed", "model"]
list_view_1.model().layoutChanged.emit()
# changing data in proxy and emitting layout change => this does not work?
list_view_2.model().<b>sourceModel()</b>.items = ["changed", "proxy+model"]
list_view_2.model().layoutChanged.emit()
# ...