在QTableVi中使用qsortfilterproxy模型对两行进行排序

2022-07-06 13:06:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我在尝试让我的过滤器为我的QTableView工作时遇到问题;目前它只适用于第一列,但是我尝试使用QLineEdit过滤前两列。它应该匹配第一列或第二列

我正在做一个最小的例子,但只是看看是否有人能看到我只是在我的代码中犯简单的错误

将for循环中的“i”更改为单个列(0或1)是可行的,但没有按预期工作,因为它只是筛选特定的列

class SortFilterProxyModel(QtCore.QSortFilterProxyModel):
    def __init__(self, *args, **kwargs):
        QtCore.QSortFilterProxyModel.__init__(self, *args, **kwargs)
        self.filters = {}

    def setFilterByColumn(self, regex, column):
        self.filters[column] = regex
        self.invalidateFilter()

    def filterAcceptsRow(self, source_row, source_parent):
        for key, regex in self.filters.items():
            ix = self.sourceModel().index(source_row, key, source_parent)
            if ix.isValid():
                text = self.sourceModel().data(ix)
                if regex.indexIn(text) == -1:
                    return False
        return True

class Database(QtWidgets.QMainWindow, Ui_databaseWindow):
    def __init__(self,parent=None):
        super().__init__()
        self.setupUi(self)
        self.mainTableView.clicked.connect(self.tableInfo)
        self.radioGroup = QtWidgets.QButtonGroup()
        self.radioGroup.addButton(self.frameView) # below are radio buttons
        self.radioGroup.addButton(self.cylView)
        self.radioGroup.addButton(self.driversView)
        self.radioGroup.addButton(self.valView)
        self.radioGroup.addButton(self.fixedView)
        self.radioGroup.addButton(self.vvcpView)
        self.frameView.setChecked(True)
        self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("C:\\Workspace\\Database\\data.db")
        self.db.open()

        self.projectModel = QtSql.QSqlQueryModel()
        self.proxyModel = SortFilterProxyModel(self)
        self.proxyModel.setSourceModel(self.projectModel)
        self.radioGroup.buttonClicked.connect(self.checkState)
        self.projectModel.setQuery("select * from tblBasic_Frame",self.db)
        self.mainTableView.setModel(self.proxyModel)
        self.mainTableView.setSortingEnabled(True)
        self.sortBox.textChanged.connect(self.onTextChanged) #QLineEdit

    @QtCore.pyqtSlot(str)
    def onTextChanged(self, text):
        if self.valveView.isChecked():
            for i in range(0,2):
                self.proxyModel.setFilterByColumn(QtCore.QRegExp(text, QtCore.Qt.CaseInsensitive),i)
        else:
            self.proxyModel.setFilterByColumn(QtCore.QRegExp(text, QtCore.Qt.CaseInsensitive),0)

Tags: textselfsourcefordbinitdeffiltersregexparentqtcoreaddbuttonproxymodelradiogroupsetfilterbycolumn
1条回答
网友
1楼 ·

您的代码有以下错误:

  • 如果第一列中的文本与文本不匹配,则返回False,表示在不考虑可能与第二列匹配的情况下不显示该行

  • 假设您已经过滤了这两列并更改了valveView的状态,这只会更新第一列的regex,所以它仍然会用以前的regex过滤第二列

  • 如果QLineEdit中没有文本,则必须清除过滤器

  • 当valveView状态更改时,还必须更新过滤器状态

class SortFilterProxyModel(QtCore.QSortFilterProxyModel):
    def __init__(self, *args, **kwargs):
        QtCore.QSortFilterProxyModel.__init__(self, *args, **kwargs)
        self.filters = {}

    def setFilterByColumn(self, regex, column):
        self.filters[column] = regex
        self.invalidateFilter()

    def clear_filter(self):
        self.filters = {}
        self.invalidateFilter()

    def filterAcceptsRow(self, source_row, source_parent):
        values = []
        if self.filters:
            for key, regex in self.filters.items():
                text = self.sourceModel().index(source_row, key, source_parent).data()
                values.append(regex.indexIn(text) != -1)
            return any(values)
        return True

class Database(QtWidgets.QMainWindow, Ui_databaseWindow):
    def __init__(self,parent=None):
        super().__init__()
        self.setupUi(self)
        self.mainTableView.clicked.connect(self.tableInfo)
        self.radioGroup = QtWidgets.QButtonGroup()
        self.radioGroup.addButton(self.frameView) # below are radio buttons
        self.radioGroup.addButton(self.cylView)
        self.radioGroup.addButton(self.driversView)
        self.radioGroup.addButton(self.valView)
        self.radioGroup.addButton(self.fixedView)
        self.radioGroup.addButton(self.vvcpView)
        self.frameView.setChecked(True)
        self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("C:\\Workspace\\Database\\data.db")
        self.db.open()

        self.projectModel = QtSql.QSqlQueryModel()
        self.proxyModel = SortFilterProxyModel(self)
        self.proxyModel.setSourceModel(self.projectModel)
        self.radioGroup.buttonClicked.connect(self.checkState)
        self.projectModel.setQuery("select * from tblBasic_Frame",self.db)
        self.mainTableView.setModel(self.proxyModel)
        self.mainTableView.setSortingEnabled(True)
        self.sortBox.textChanged.connect(self.update_filter) #QLineEdit
        self.valveView.toggled.connect(self.update_filter)

    @QtCore.pyqtSlot()
    def update_filter(self):
        text = self.sortBox.text()
        self.proxyModel.clear_filter()
        if text:
            if self.valveView.isChecked():
                for i in range(2):
                    self.proxyModel.setFilterByColumn(
                        QtCore.QRegExp(text, QtCore.Qt.CaseInsensitive), i
                    )
            else:
                self.proxyModel.setFilterByColumn(
                    QtCore.QRegExp(text, QtCore.Qt.CaseInsensitive), 0
                )