2017-01-20 6 views
0

ich QTableWidget bin mit verwenden csv Daten anzuzeigen. Wenn ich ein Schlüsselwort eingeben möchte, möchte ich, dass die Filteraktion ähnlich wie Excel ausgeführt wird. Es sollte sich auf alle Zeilen und Spalten auswirken.Wie Filter Option in 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 ist Objektnamen fot QTableWidget

.ui Code:

<?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

Können Sie uns auch den Inhalt filter.ui zeigen? – eyllanesc

+0

Wie soll der Filter funktionieren? – eyllanesc

+0

@eyllanesc Wenn ich filtere, muss es alle Zeilen beeinflussen. Etwas wie in Excel. Nehmen wir an, es gibt 12 Spalten. Wenn ich auf die Kopfzeile klicke, müssen alle möglichen Texte angezeigt werden und nach der Auswahl müssen nur diese angezeigt werden. Und wenn jemand etwas in die Suchleiste eingibt, muss er in 3,4,5,6 Spalten suchen ... –

Antwort

0

durch Klicken auf die Kopfzeile jeder Spalte gefiltert wird, wird es die möglichen Werte zeigen, und sie überprüft wird filtern.

komplette Code:

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

Vielen Dank ... Es funktioniert super und gut, wie ich es erwartet hatte. Aber es gibt ein Problem. Ich habe bereits eine GUI in QtDesigner gemacht. Wird es irgendein Problem verursachen, wenn ich diese Klasse dort hinzufüge? –

+0

@PradyumnaCheerala ich ein Projekt laden mit Ihrem Code GitHub, die Sie haben in wenigen Stunden gezeigt und mein Projekt. – eyllanesc

+0

@PradyumnaCheerala vollständiger Code: https://github.com/eyllanesc/stackoverflow/tree/master/FilterTable – eyllanesc