How to create filters for QTableView in PyQt

I use QTableView to display data retrieved from QtSql.QSqlQuery

I want to know how to create filters for it, as in excel.

enter image description here

In the above image, I need to get filters for All heders (Sh_Code, SH_Seq, Stage) Filters will have unique values ​​in the column on which we can filter.

Desired Result

I need a table view title with dropbox listing all the unique values ​​in this column, as in excel below. There is no need for an upper, standard filter ... as shown. Only "All" and unique "columns" are needed.

enter image description here

This is from my .NET application, loaded for clarity.

enter image description here

+8
python qt pyqt pyqt4 qtableview
source share
1 answer

Here is an example of filtering in PyQt using QSortFilterProxyModel , QStandardItemModel and QTableView , it can be easily adapted to other views and models:

 #!/usr/bin/env python #-*- coding:utf-8 -*- from PyQt4 import QtCore, QtGui class myWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(myWindow, self).__init__(parent) self.centralwidget = QtGui.QWidget(self) self.lineEdit = QtGui.QLineEdit(self.centralwidget) self.view = QtGui.QTableView(self.centralwidget) self.comboBox = QtGui.QComboBox(self.centralwidget) self.label = QtGui.QLabel(self.centralwidget) self.gridLayout = QtGui.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 = QtGui.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 = QtGui.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 = QtGui.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 = QtGui.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 = QtGui.QApplication(sys.argv) main = myWindow() main.show() main.resize(400, 600) sys.exit(app.exec_()) 

To get the desired results, a pop-up menu is launched by clicking on the header and filled with unique values ​​for this column. Once the item in the popup menu is selected, the value is passed to self.proxy.setFilterRegExp(filterString) , and the column to self.proxy.setFilterKeyColumn(filterValue) .

image

+16
source share

All Articles