How to create filters for QTableView in PyQt

后端 未结 3 1065
悲哀的现实
悲哀的现实 2020-12-23 15:27

I am using QTableView to display data retrieved from QtSql.QSqlQuery

I want to know how can i create filters for it like in excel.

3条回答
  •  礼貌的吻别
    2020-12-23 15:47

    I tried to update the answer provided in the above for PyQt5

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class myWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(myWindow, self).__init__(parent)
            self.centralwidget  = QtWidgets.QWidget(self)
            self.lineEdit       = QtWidgets.QLineEdit(self.centralwidget)
            self.view           = QtWidgets.QTableView(self.centralwidget)
            self.comboBox       = QtWidgets.QComboBox(self.centralwidget)
            self.label          = QtWidgets.QLabel(self.centralwidget)
    
            self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
            self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
            self.gridLayout.addWidget(self.view, 1, 0, 1, 3)
            self.gridLayout.addWidget(self.comboBox, 0, 2, 1, 1)
            self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
    
            self.setCentralWidget(self.centralwidget)
            self.label.setText("Regex Filter")
    
            self.model = QtGui.QStandardItemModel(self)
    
            for rowName in range(3*5):
                self.model.invisibleRootItem().appendRow(
                    [   QtGui.QStandardItem("row {0} col {1}".format(rowName, column))    
                        for column in range(3)
                        ]
                    )
    
            self.proxy = QtCore.QSortFilterProxyModel(self)
            self.proxy.setSourceModel(self.model)
    
            self.view.setModel(self.proxy)
            self.comboBox.addItems(["Column {0}".format(x) for x in range(self.model.columnCount())])
    
            self.lineEdit.textChanged.connect(self.on_lineEdit_textChanged)
            self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)
    
            self.horizontalHeader = self.view.horizontalHeader()
            self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked)
    
        @QtCore.pyqtSlot(int)
        def on_view_horizontalHeader_sectionClicked(self, logicalIndex):
            self.logicalIndex   = logicalIndex
            self.menuValues     = QtWidgets.QMenu(self)
            self.signalMapper   = QtCore.QSignalMapper(self)  
    
            self.comboBox.blockSignals(True)
            self.comboBox.setCurrentIndex(self.logicalIndex)
            self.comboBox.blockSignals(True)
    
            valuesUnique = [    self.model.item(row, self.logicalIndex).text()
                                for row in range(self.model.rowCount())
                                ]
    
            actionAll = QtWidgets.QAction("All", self)
            actionAll.triggered.connect(self.on_actionAll_triggered)
            self.menuValues.addAction(actionAll)
            self.menuValues.addSeparator()
    
            for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):              
                action = QtWidgets.QAction(actionName, self)
                self.signalMapper.setMapping(action, actionNumber)  
                action.triggered.connect(self.signalMapper.map)  
                self.menuValues.addAction(action)
    
            self.signalMapper.mapped.connect(self.on_signalMapper_mapped)  
    
            headerPos = self.view.mapToGlobal(self.horizontalHeader.pos())        
    
            posY = headerPos.y() + self.horizontalHeader.height()
            posX = headerPos.x() + self.horizontalHeader.sectionPosition(self.logicalIndex)
    
            self.menuValues.exec_(QtCore.QPoint(posX, posY))
    
        @QtCore.pyqtSlot()
        def on_actionAll_triggered(self):
            filterColumn = self.logicalIndex
            filterString = QtCore.QRegExp(  "",
                                            QtCore.Qt.CaseInsensitive,
                                            QtCore.QRegExp.RegExp
                                            )
    
            self.proxy.setFilterRegExp(filterString)
            self.proxy.setFilterKeyColumn(filterColumn)
    
        @QtCore.pyqtSlot(int)
        def on_signalMapper_mapped(self, i):
            stringAction = self.signalMapper.mapping(i).text()
            filterColumn = self.logicalIndex
            filterString = QtCore.QRegExp(  stringAction,
                                            QtCore.Qt.CaseSensitive,
                                            QtCore.QRegExp.FixedString
                                            )
    
            self.proxy.setFilterRegExp(filterString)
            self.proxy.setFilterKeyColumn(filterColumn)
    
        @QtCore.pyqtSlot(str)
        def on_lineEdit_textChanged(self, text):
            search = QtCore.QRegExp(    text,
                                        QtCore.Qt.CaseInsensitive,
                                        QtCore.QRegExp.RegExp
                                        )
    
            self.proxy.setFilterRegExp(search)
    
        @QtCore.pyqtSlot(int)
        def on_comboBox_currentIndexChanged(self, index):
            self.proxy.setFilterKeyColumn(index)
    
    
    if __name__ == "__main__":
        import sys
    
        app  = QtWidgets.QApplication(sys.argv)
        main = myWindow()
        main.show()
        main.resize(400, 600)
        sys.exit(app.exec_())
    

提交回复
热议问题