I have been struggling with this for a while, and i am not even sure i am using the right pyqt classes.
I have a QTableView that display a 2d array of integers and i wish to filter it to only show the integer under a value.
This is the example:
from PyQt4 import QtCore, QtGui
import random
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None):
super(TableModel, self).__init__(parent)
self._columns = 3
self._parent = parent
def rowCount(self, parent=QtCore.QModelIndex()):
return int( float( len( self._parent.data ) ) / float( self._columns ) )+1
def columnCount(self, parent=QtCore.QModelIndex()):
return self._columns
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if role == QtCore.Qt.DisplayRole:
try:
value = self._parent.data[ index.row() * self._columns + index.column() ]
except:
pass
else:
return value
return None
class tableProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self, parent=None):
super(tableProxyModel, self).__init__(parent)
self._parent = parent
self.filterColumn = []
self.filterRow = []
self.maxFilter =0
def setFilter(self, value):
#
# this will find the 2d position of the datas that need to be kept visible
# we need a list of the row and column axis
#
self.maxFilter = value
self.filterColumn = []
self.filterRow = []
for i in self._parent.data:
if i < self.maxFilter:
positionInList = [j for j,x in enumerate( self._parent.data ) if x == i][0]
filterRow, filterColumn = self.getPosition( positionInList )
self.filterColumn.append(filterColumn)
self.filterRow.append(filterRow)
self.invalidateFilter()
def getPosition(self, value):
#
# convert data list to a 2d array
#
leftOver = value%self._parent._tm._columns
filterRow = (value-leftOver) / self._parent._tm._columns
filterColumn = leftOver
return filterRow, filterColumn
def filterAcceptsRow(self, row, parent):
model = self.sourceModel()
if row in self.filterRow:
return True
else:
return False
def filterAcceptsColumn(self, column, parent):
model = self.sourceModel()
if column in self.filterColumn:
return True
else:
return False
if __name__=="__main__":
from sys import argv, exit
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.data = [ d for d in range(10) ]
###################################################
## this line shuffle the list, if you quote this line and keep the list in order , then the example works as expected
random.shuffle(self.data)
print self.data
l=QtGui.QVBoxLayout( self )
self._tm=TableModel( self )
self._tv=QtGui.QTableView( )
self._tpm=tableProxyModel( self )
self._tpm.setSourceModel( self._tm )
self._tv.setModel( self._tpm )
l.addWidget( self._tv )
#################################################
## apply the filter, only show numbers under 5
self._tpm.setFilter(5)
a=QtGui.QApplication(argv)
w=Widget()
w.show()
w.raise_()
exit(a.exec_())
If you execute this example, you can see it doesn't only show the values under 5 ...
How can i filter a QTableView filled with random values ? I wish to use the model/view system here.