首页 > 解决方案 > QStandardItemModel 的 setData、setItemData 和 setIem 方法有什么区别?

问题描述

我很困惑如何使用setDatasetItemDatasetItem方法QStandardItemModel,这些方法似乎具有相同的效果,我想知道我应该选择哪种方法最好?

class DemoD(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        table = QTableView()
        model = QStandardItemModel(4, 2)

        table.setModel(model)

        # delegate = SpinBoxDelegate()

        # table.setItemDelegate(delegate)

        for row in range(4):
            for col in range(2):
                item = QStandardItem('china')
                model.setItem(row, col, item)

                index = model.index(row, col)
                value = QVariant((row + 1)*(col + 1))
                model.setData(index, value)

                model.setItemData(index, {1: 'a', 2: 'b'})

        self.setCentralWidget(table)

        self.resize(400, 300)

app = QApplication([])
demo = DemoD()
demo.show()
app.exec()

标签: pyqtpyqt5qabstractitemmodel

解决方案


如果您想了解 Qt 模型的概念,您应该阅读以下指南:

以前的概念:

  • QStandarItemModel:它是一个继承自 QAbstractItemModel 的类,它允许存储任何类型的信息,这与仅定义行为的 QAbstractItemModel 不同。

考虑到您已经仔细阅读了前面的链接,我们将尝试解释您指出的不同方法之间的区别:

  • setData():每个 Qt 模型都继承自 QAbstractItemModel,所以这个类定义了一般行为,在这种情况下,定义了 setData() 模型负责修改与 QModelIndex 关联的角色的信息。换句话说,如果要实现可编辑模型,则必须实现通用方法,例如 QStringListModel 不是可编辑模型,因此它不会实现它,但在 QStandardItemModel 的情况下,它是可编辑的,因此您可以修改通过该方法获取模型的信息。

  • setItem(): QStandardItem 是 QStandardItemModel 的概念,在概念上类似于 QModelIndex。此元素允许您轻松地与 QModelIndex 交互。如果 QStandardItem 没有与模型关联,它只会存储信息,在分配模型时,所有信息都会传递给模型,并且模型会通知您可以通过其他方法(例如 setData)进行的任何更改。与模型的 setData 等效的是 QStandardItem 的 setData 方法,但后者不需要提供 QModelIndex,因为该信息是内部可用的,或者可以在建立模型时获得。

例如:

it.setText("foo")
it.setTextAlignment(QtCore.Qt.AlignCenter)

相当于

it.model().setData(it.index(), "foo", QtCore.Qt.DisplayRole)
it.model().setData(it.index(), QtCore.Qt.AlignCenter, QtCore.Qt.TextAlignmentRole)

如您所见,QStandardItem 允许您以简单的方式修改项目的信息,并且通过简单的方式您可以说它是模型的项目。

  • setItemData():这是一种方法,允许您通过检查角色是否有效来修改与 QModelIndex 关联的多个角色的信息,通常如果您使用无效模型,该方法不会更新信息,但在处理通用信息的 QStandardItemModel 确定所有角色对于始终有效的内容都是有效的。

在 QStandardItemModel 的情况下,以下代码是等效的:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    model = QtGui.QStandardItemModel(1, 1)
    it = QtGui.QStandardItem()
    model.setItem(0, 0, it)

    # The following lines modify the text shown
    # to be related to the Qt::DisplayRole role and
    # the QModelIndex associated with the QStandardItem:
    it.setText("foo")
    it.setData("foo", QtCore.Qt.DisplayRole)
    model.setData(it.index(), "foo", QtCore.Qt.DisplayRole)
    model.setItemData(it.index(), {QtCore.Qt.DisplayRole: "foo"})

    # The same as the previous lines but in the case of
    # the background and the text colors of the item.
    it.setForeground(QtGui.QColor("red"))
    it.setBackground(QtGui.QColor("blue"))
    it.setData(QtGui.QColor("red"), QtCore.Qt.ForegroundRole)
    it.setData(QtGui.QColor("blue"), QtCore.Qt.BackgroundRole)
    model.setData(it.index(), QtGui.QColor("red"), QtCore.Qt.ForegroundRole)
    model.setData(it.index(), QtGui.QColor("blue"), QtCore.Qt.BackgroundRole)
    model.setItemData(
        it.index(),
        {
            QtCore.Qt.ForegroundRole: QtGui.QColor("red"),
            QtCore.Qt.BackgroundRole: QtGui.QColor("blue"),
        },
    )

推荐阅读