首页 > 解决方案 > PyQt5 - 使用 QSortFilterProxyModel --> filterAcceptsRow 时退出代码 3

问题描述

我试图在 PyQt5 (Python 3.7 -IDE PyCharm) 中使用 QSortFilterProxyModel。我总是得到“进程完成,退出代码 3”,没有其他反应。这是我用来尝试的代码(也在 Stackoverflow 中找到):

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class Model(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)
    def columnCount(self, parent=QModelIndex()):
        return 1

    def data(self, index, role):
        if not index.isValid(): return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()

        row=index.row()
        if row<len(self.items):
            return QVariant(self.items[row])
        else:
            return QVariant()

class Proxy(QSortFilterProxyModel):
    def __init__(self):
        super(Proxy, self).__init__()

    def filterAcceptsRow(self, row, parent):
        if '_B_' in self.sourceModel().data(self.sourceModel().index(row, 0), Qt.DisplayRole).toPyObject():
            return True
        return False

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        tableModel=Model(self)

        proxyModel=Proxy()
        proxyModel.setSourceModel(tableModel)

        self.tableview=QTableView(self)
        self.tableview.setModel(proxyModel)
        self.tableview.clicked.connect(self.viewClicked)
        self.tableview.horizontalHeader().setStretchLastSection(True)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tableview)
        self.setLayout(layout)

    def viewClicked(self, indexClicked):
        print('index of proxy row', indexClicked.row())

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

提前感谢您的帮助。

标签: pythonpyqtpyqt5qabstractitemmodelqsortfilterproxymodel

解决方案


在 PyQt5QVariant中不再需要,直接将数据转换为 python 的原生类型,因此QVariant不再存在 method toPyObject(),因此必须将模型和代理更改为以下内容:

class Model(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)

    def columnCount(self, parent=QModelIndex()):
        return 1

    def data(self, index, role=Qt.DisplayRole):
        row = index.row()
        if 0 <= row < self.rowCount() and role == Qt.DisplayRole:
            return self.items[row]


class Proxy(QSortFilterProxyModel):
    def filterAcceptsRow(self, row, parent):
        return '_B_' in self.sourceModel().data(self.sourceModel().index(row, 0))

有关更多信息,请阅读http://pyqt.sourceforge.net/Docs/PyQt5/pyqt_qvariant.html


推荐阅读