2012-12-28 33 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