2012-12-28 11 views
7

Używam QTableView aby wyświetlać dane pobrane z QtSql.QSqlQueryJak tworzyć filtry dla QTableView w PyQt

Chcę wiedzieć, w jaki sposób można utworzyć filtry dla niego jak w programie Excel.

enter image description here

W powyższym obrazie muszę dostać filtry dla wszystkich chederów (Sh_Code, SH_Seq, Stage) Filtry będą mieć unikalne wartości w tej kolumnie, na której możemy filtrować.

wynik Wymagane

muszę nagłówek widoku tabeli z Dropbox wymieniając wszystkie unikalne wartości w tej kolumnie, podobnie jak w programie Excel poniżej. Nie ma potrzeby stosowania filtra górnego, standardowego ... jak pokazano na rysunku. Potrzebujesz tylko „All” i „unikalne przedmioty kolumna”

enter image description here

To z mojej aplikacji .NET, przesłanych do większej przejrzystości

enter image description here

Odpowiedz

15

Oto przykład z filtrowaniem w PyQt stosując QSortFilterProxyModel, QStandardItemModel i QTableView, można go łatwo dostosować do innych poglądów i modeli:

#!/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_()) 

Aby uzyskać wymagane wyniki, należy otworzyć menu podręczne, klikając nagłówek i wypełnić unikalnymi wartościami dla tej kolumny. Po wybraniu pozycji w menu podręcznym wartość jest przekazywana do self.proxy.setFilterRegExp(filterString), a kolumna do self.proxy.setFilterKeyColumn(filterValue).

image

+0

To nie otrzymuję żadnych rzeczy filtrowane po wpisaniu "row 0 col 0" w polu filtra. Dodałem instrukcje drukowania w 'on_lineEdit_textChanged'' on_comboBox_currentIndexChanged', ale nigdy nie są wykonywane. Pracuję nad Pythonem 2.6.4 – Rao

+0

@PBLNarasimhaRao Zapomniałem połączyć gniazda! Zaktualizowałem [kod] (http://stackoverflow.com/a/14075797/1006989), powinien działać teraz –

+0

zadziałał poprzez połączenie sygnałów 'self.comboBox.currentIndexChanged.connect (self.on_comboBox_currentIndexChanged)' i ' self.lineEdit.textChanged.connect (self.on_lineEdit_textChanged) 'Ale potrzebuję filtrów, które będą wyświetlane w nagłówkach kolumn, skąd mogę je wybrać (na przykład jak w programie Excel). zaktualizowałem to pytanie za pomocą migawki programu Excel, która jest wymagana. – Rao

Powiązane problemy