python - 如何触发模型更新它链接到的列表

标签 python qt pyqt

self.viewAQListView,它通过其 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?

enter image description here

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...
  • 为模型订阅新类的信号并调用适当的方法:beginInsertRowsendInsertRowsbeginRemoveRowsendRemoveRows, 发出 dataChanged...

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

关于python - 如何触发模型更新它链接到的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149965/

相关文章:

python - PyQt 中的 QGraphicsItem 什么时候被销毁?

python - 为每个子列表的第一个元素赋值的更简单方法?

python - 使用 argparse 启动 flask 服务器

python - if/elif 语句的多个条件

c++ - Qt中的实时像素绘制

qt - 将 Gstreamer 与 Qt 连接以便在 Qt Widget 中播放 gstreamer 视频

python - 如何在 PyQt 中使用 QRubberBand 和 QRect 类?

python - 绘制 PyQt 小部件背景时出现意外消息

python - 如何返回与用户端点一起验证的电子邮件?

qt - 如何从 QTableView 中获取选中的行号?