2012-12-28 61 views
7

創建過濾器QTableView中我使用QTableView中顯示我想知道我可以爲它創建過濾器像在Excel中從QtSql.QSqlQuery如何PyQt的

檢索到的數據。

enter image description here

在上圖中我需要得到過濾器所有heders(Sh_Code,SH_Seq,舞臺) 過濾器將在該列上,我們可以篩選的唯一值。

所需的結果

我所需要的表視圖頭與Dropbox的列出該列中的所有唯一值,就像在下面的Excel。不需要頂部,標準過濾器......如圖所示。只有「所有」和獨特的「物品欄」

enter image description here

這是從我的.NET應用程序所需要的,上傳更加清晰

enter image description here

回答

15

這裏是濾波的PyQt的一個例子使用QSortFilterProxyModel,QStandardItemModelQTableView,它可以很容易地適應其他意見和型號:

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

要獲得所需的結果,可以通過單擊標題來啓動一個彈出式菜單,並填充該列的唯一值。一旦選擇了彈出菜單中的項目,該值將被傳遞到self.proxy.setFilterRegExp(filterString),並且該列將被傳遞到self.proxy.setFilterKeyColumn(filterValue)

image

+0

它沒有得到任何過濾的事情時,我在過濾器中鍵入「行0山坳0」。我在'on_lineEdit_textChanged''on_comboBox_currentIndexChanged'中添加了打印語句,但它們從不執行。我正在使用Python 2.6.4 – Rao

+0

@PBLNarasimhaRao忘記連接插槽!我更新了[代碼](http://stackoverflow.com/a/14075797/1006989),它現在應該工作 – 2013-01-02 07:47:35

+0

它通過連接信號'self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)'和' self.lineEdit.textChanged.connect(self.on_lineEdit_textChanged)'但我需要在列標題上顯示過濾器,從那裏我可以選擇它(例如像在Excel中)。我已經用需要的Excel快照更新了這個問題。 – Rao