2017-01-20 2 views
0

J'utilise QTableWidget pour afficher les données CSV. Lorsque je saisis un mot-clé, je souhaite que l'action de filtrage soit similaire à celle d'Excel. Cela devrait affecter toutes les lignes et colonnes.Comment utiliser l'option de filtrage dans QTableWidget

from PyQt4 import QtCore, QtGui, uic 
from PyQt4.QtCore import QString 

from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

import MySQLdb 
import os 
import time 
import sys 
import hashlib 
import getpass 
import webbrowser 
import csv 

filter_class = uic.loadUiType("filter.ui")[0] 

class Filter_window(QtGui.QWidget, filter_class): 
    def __init__(self, parent=None, *args, **kwargs): 
     QtGui.QMainWindow.__init__(self, parent) 
     self.setupUi(self) 

     #self.selectall.clicked.connect(self.selectall_application) 
     #self.filnext.clicked.connect(self.filnext_application) 

     self.loadAll() 


    def loadAll(self): 

     with open("Rts.csv", "rb") as inpfil: 

      reader = csv.reader(inpfil, delimiter = ',') 
      csheader = reader.next() 
      ncol = len(csheader) 
      data = list(reader) 
      row_count = len(data) 

      self.filterall.setRowCount(row_count) 
      self.filterall.setColumnCount(ncol) 
      self.filterall.setHorizontalHeaderLabels(QString('%s' % ', '.join(map(str, csheader))).split(",")) 

      for ii in range(0, row_count): 
       print data[ii] 

       mainins = data[ii] 
       print mainins 


       for var in range(0,ncol):             
        print mainins[var], "\n" 
        self.filterall.setItem(ii, var, QTableWidgetItem(mainins[var])) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    filterwin = Filter_window() 
    filterwin.show() 
    sys.exit(app.exec_()) 

filterall est le nom d'objet fot QTableWidget

Code .ui:

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>allCases</class> 
<widget class="QWidget" name="allCases"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>597</width> 
    <height>466</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>All Cases</string> 
    </property> 
    <layout class="QGridLayout" name="gridLayout"> 
    <item row="3" column="0" colspan="4"> 
    <widget class="Line" name="line"> 
    <property name="orientation"> 
     <enum>Qt::Horizontal</enum> 
    </property> 
    </widget> 
    </item> 
    <item row="4" column="3"> 
    <widget class="QPushButton" name="filnext"> 
    <property name="font"> 
     <font> 
     <pointsize>12</pointsize> 
     </font> 
    </property> 
    <property name="text"> 
     <string>Next</string> 
    </property> 
    </widget> 
    </item> 
    <item row="4" column="2"> 
    <widget class="QPushButton" name="selectall"> 
    <property name="font"> 
     <font> 
     <pointsize>12</pointsize> 
     </font> 
    </property> 
    <property name="text"> 
     <string>Select All</string> 
    </property> 
    </widget> 
    </item> 
    <item row="0" column="1"> 
    <widget class="QLineEdit" name="filterEdit"> 
    <property name="toolTip"> 
     <string/> 
    </property> 
    <property name="statusTip"> 
     <string/> 
    </property> 
    <property name="placeholderText"> 
     <string>Enter keyword to search</string> 
    </property> 
    </widget> 
    </item> 
    <item row="0" column="2"> 
    <spacer name="horizontalSpacer"> 
    <property name="orientation"> 
     <enum>Qt::Horizontal</enum> 
    </property> 
    <property name="sizeHint" stdset="0"> 
     <size> 
     <width>40</width> 
     <height>20</height> 
     </size> 
    </property> 
    </spacer> 
    </item> 
    <item row="1" column="0" colspan="4"> 
    <widget class="QTableWidget" name="filterall"/> 
    </item> 
    </layout> 
</widget> 
<resources/> 
<connections/> 
</ui> 
+0

Pourriez-vous nous montrer le contenu de filter.ui? – eyllanesc

+0

Comment voulez-vous que le filtre fonctionne? – eyllanesc

+0

@eyllanesc Si je filtre, il doit effectuer toutes les lignes. Quelque chose comme dans Excel. laisse supposer qu'il y a 12 colonnes. Sur l'en-tête si je clique, il doit afficher tous les textes possibles et après sélection, il ne doit montrer que ceux-là. Et aussi, si quelqu'un tape quelque chose dans la barre de recherche, il doit chercher dans les colonnes 3,4,5,6 ... –

Répondre

0

Il est filtré en cliquant sur l'en-tête de chaque colonne, il affichera les valeurs possibles, et les vérifier va filtrer.

Code complet:

import csv 
import sys 
from PyQt4 import QtCore 

from PyQt4 import QtGui 


class Widget(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(Widget, self).__init__(parent=parent) 
     self.verticalLayout = QtGui.QVBoxLayout(self) 
     self.filterall = QtGui.QTableWidget(self) 
     self.filterall.setColumnCount(0) 
     self.filterall.setRowCount(0) 
     self.verticalLayout.addWidget(self.filterall) 

     self.loadAll() 
     self.horizontalHeader = self.filterall.horizontalHeader() 
     self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked) 
     self.keywords = dict([(i, []) for i in range(self.filterall.columnCount())]) 
     self.checkBoxs = [] 
     self.col = None 

    def slotSelect(self, state): 

     for checkbox in self.checkBoxs: 
      checkbox.setChecked(QtCore.Qt.Checked == state) 

    def on_view_horizontalHeader_sectionClicked(self, index): 
     # self.clearFilter() 
     self.menu = QtGui.QMenu(self) 
     self.col = index 

     data_unique = [] 

     self.checkBoxs = [] 

     checkBox = QtGui.QCheckBox("Select all", self.menu) 
     checkableAction = QtGui.QWidgetAction(self.menu) 
     checkableAction.setDefaultWidget(checkBox) 
     self.menu.addAction(checkableAction) 
     checkBox.setChecked(True) 
     checkBox.stateChanged.connect(self.slotSelect) 

     for i in range(self.filterall.rowCount()): 
      if not self.filterall.isRowHidden(i): 
       item = self.filterall.item(i, index) 
       if item.text() not in data_unique: 
        data_unique.append(item.text()) 
        checkBox = QtGui.QCheckBox(item.text(), self.menu) 
        checkBox.setChecked(True) 
        checkableAction = QtGui.QWidgetAction(self.menu) 
        checkableAction.setDefaultWidget(checkBox) 
        self.menu.addAction(checkableAction) 
        self.checkBoxs.append(checkBox) 

     btn = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, 
            QtCore.Qt.Horizontal, self.menu) 
     btn.accepted.connect(self.menuClose) 
     btn.rejected.connect(self.menu.close) 
     checkableAction = QtGui.QWidgetAction(self.menu) 
     checkableAction.setDefaultWidget(btn) 
     self.menu.addAction(checkableAction) 

     headerPos = self.filterall.mapToGlobal(self.horizontalHeader.pos()) 

     posY = headerPos.y() + self.horizontalHeader.height() 
     posX = headerPos.x() + self.horizontalHeader.sectionPosition(index) 
     self.menu.exec_(QtCore.QPoint(posX, posY)) 

    def menuClose(self): 
     self.keywords[self.col] = [] 
     for element in self.checkBoxs: 
      if element.isChecked(): 
       self.keywords[self.col].append(element.text()) 
     self.filterdata() 
     self.menu.close() 

    def loadAll(self): 
     with open("Rts.csv", "rb") as inpfil: 
      reader = csv.reader(inpfil, delimiter=',') 
      csheader = reader.next() 
      ncol = len(csheader) 
      data = list(reader) 
      row_count = len(data) 

      self.filterall.setRowCount(row_count) 
      self.filterall.setColumnCount(ncol) 
      self.filterall.setHorizontalHeaderLabels(QtCore.QString('%s' % ', '.join(map(str, csheader))).split(",")) 

      for ii in range(0, row_count): 
       mainins = data[ii] 
       for var in range(0, ncol): 
        self.filterall.setItem(ii, var, QtGui.QTableWidgetItem(mainins[var])) 

    def clearFilter(self): 
     for i in range(self.filterall.rowCount()): 
      self.filterall.setRowHidden(i, False) 

    def filterdata(self): 

     columnsShow = dict([(i, True) for i in range(self.filterall.rowCount())]) 

     for i in range(self.filterall.rowCount()): 
      for j in range(self.filterall.columnCount()): 
       item = self.filterall.item(i, j) 
       if self.keywords[j]: 
        if item.text() not in self.keywords[j]: 
         columnsShow[i] = False 
     for key, value in columnsShow.iteritems(): 
      self.filterall.setRowHidden(key, not value) 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    w = Widget() 
    w.show() 
    sys.exit(app.exec_()) 

enter image description here

+0

Merci beaucoup ... Il fonctionne très bien et bien comme je m'y attendais. Mais il y a un problème. J'ai déjà une interface graphique dans QtDesigner. Cela créera-t-il un problème si j'ajoute cette classe là-bas? –

+0

@PradyumnaCheerala Je télécharge un projet sur github avec votre code que vous avez montré et mon projet dans quelques heures. – eyllanesc

+0

@PradyumnaCheerala code complet: https://github.com/eyllanesc/stackoverflow/tree/master/FilterTable – eyllanesc