如何触发模型更新其链接到的列表

alp*_*ric 3 python qt pyqt

self.viewA是并且它通过其对象实例QListView进行填充。对象实例从全局声明的列表变量获取其数据。后来数据列表变量被修改(添加数据)。在这样的数据列表变量更改中,我想触发一个,以便它继续并使用新项目进行更新。到目前为止,我知道触发的唯一方法是发出信号:QAbstractTableModelQAbstractTableModelitemsitemsQAbstractTableModelQListViewQAbstractTableModel

myQListView.model().emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), QtCore.QModelIndex(), QtCore.QModelIndex())
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

myQListView.model().reset()
Run Code Online (Sandbox Code Playgroud)

但这没有帮助。所以问题是当 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_())
Run Code Online (Sandbox Code Playgroud)

Eze*_*zee 5

有两种方法,每次使用模型视图时都应该实现其中一种。

模型作为数据存储

  • 将您的变量items放入ListModel. 使用 的方法修改项目ListModel
    例如,要追加一行,您可以使用QAbstractItemModel: insertRow和 then方法setData
  • 重新实现insertRows:调用beginInsertRowsadd new rows intoitems并调用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, emit dataChanged...

为什么采用这两种方法?因为模型应该与数据同步。如果您可以修改模型外部的数据,您可能会遇到很多问题。