self.viewA
是 QListView
,它通过其 QAbstractTableModel
对象实例进行填充。 QAbstractTableModel
对象实例从全局声明的 items
列表变量中获取数据。稍后 items
data-list-variable 被修改(添加数据)。在这样的数据列表变量更改中,我想触发一个 QAbstractTableModel
,以便它继续并用新项目更新 QListView
。到目前为止,我知道触发 QAbstractTableModel
的唯一方法是发出信号:
myQListView.model().emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), QtCore.QModelIndex(), QtCore.QModelIndex())
我也试过:
myQListView.model().reset()
但这并没有帮助。所以问题是当 QListView 模型使用的数据变量被修改时如何更新 QListView?
from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)
items=['Item 0','Item 1','Item 2']
class ListModel(QtCore.QAbstractTableModel):
def __init__(self):
QtCore.QAbstractTableModel.__init__(self)
def rowCount(self, parent=QtCore.QModelIndex()):
return len(items)
def columnCount(self, parent=QtCore.QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid() or not (0<=index.row()<len(items)): return QtCore.QVariant()
key=str(items[index.row()])
if role==QtCore.Qt.DisplayRole:
return key
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
mainLayout=QtGui.QVBoxLayout()
self.setLayout(mainLayout)
model=ListModel()
self.viewA=QtGui.QListView()
self.viewA.setModel(model)
button=QtGui.QPushButton('Add Item')
button.clicked.connect(self.onClick)
mainLayout.addWidget(self.viewA)
mainLayout.addWidget(button)
self.show()
def onClick(self, index):
items.append('Item %s'%len(items))
self.viewA.model().emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), QtCore.QModelIndex(), QtCore.QModelIndex())
# self.viewA.model().reset()
window=Window()
sys.exit(app.exec_())
最佳答案
有两种方法,每次您使用模型 View 时都应实现其中一种。
模型作为数据存储
- 将变量
items
放入ListModel
。使用ListModel
的方法修改项目。
例如,要追加一行,您可以使用QAbstractItemModel
的方法:insertRow
,然后是setData
。 - 重新实现
insertRows
:调用beginInsertRows
将新行添加到items
并调用endInsertRows
。 - 重新实现
removeRows
- 重新实现
setData
并适本地发出信号dataChanged
。 - 您还可以向模型添加新方法以便于使用:
appendData
...
模型作为适配器
这是一个理论:https://qt-project.org/doc/note_revisions/13/28/view
这种方法需要更多代码,但更可靠且可扩展。
- 创建一个继承自
QObject
的新类,并将items
放在那里。创建从外部修改项目的方法。发射信号itemAboutToBeAdded
,itemAdded
,itemAboutToBeRemoved
,itemRemoved
,itemChanged
... - 为模型订阅新类的信号并调用适当的方法:
beginInsertRows
、endInsertRows
、beginRemoveRows
、endRemoveRows
,发出 dataChanged
...
为什么使用这两种方法?因为模型应该与数据同步。如果您可以修改模型外的数据,您会遇到很多问题。
关于python - 如何触发模型更新它链接到的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149965/