首页 > 解决方案 > 漏洞?在 PyQt5 中为 QStandardItemModel 实现 rowCount() 有奇怪的效果

问题描述

我只是想实现反对QStandardItemModel并试图rowCount()返回 |rows| + 1 显示额外的一行。我会实施data()flags()相应地显示额外行的有效值。

但现在我很困惑。额外的线被绘制(因此该方法被正确实现),但data()flags()始终使用内部数据模型内的索引调用。此外,我的应用在大约 50% 的情况下会崩溃。

所以它看起来并不适用于应该rowCount()使用它的所有情况,这会导致对内部数据的无效访问..

这是一个错误吗?

我在 Linux (Ubuntu 18.04) 上使用 PyQt5-5.14.0

from PyQt5 import QtWidgets, QtGui, QtCore


class MyModel(QtGui.QStandardItemModel):
    def __init__(self):
        super().__init__()
        self.appendRow([QtGui.QStandardItem("Hi"), QtGui.QStandardItem("there")])
        self.appendRow([QtGui.QStandardItem("Hello"), QtGui.QStandardItem("world")])

    def rowCount(self, parent):
        return super().rowCount() + 1

    def data(self, index: QtCore.QModelIndex, role: QtCore.Qt.ItemDataRole):
        assert index.row() < 2  # index.row() is always in [-1, 0, 1]
        return super().data(index, role)

    def flags(self, index: QtCore.QModelIndex) -> QtCore.Qt.ItemFlags:
        assert index.row() < 2  # index.row() is always in [-1, 0, 1]
        return super().flags(index)


class Testing(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        model = MyModel()
        view = QtWidgets.QTableView(self)
        view.setModel(model)
        self.setCentralWidget(view)
        self.show()


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    test = Testing()
    raise SystemExit(app.exec_())

标签: python-3.xpyqtpyqt5

解决方案


我忘了实施index()

def index(self, row, column, parent):
    return super().index(row, column) if row < super().rowCount() else self.createIndex(row, column)

解释:super().index()将为行创建无效索引 > |内部数据| 这导致flags()data()根本不被调用。


推荐阅读