Hi all readers,
I've got a Model (a sub class of QAbstractTableModel) that work like a charm what ever the standard view I plug it in, that do not support the sort function.
But this model as 'too' many columns most of the time... (thinks of it as the result of select * from table).
So I build a simple model that filter columns, here is the code (in python) (btw I wanted to use QIdentityProxyModel but it does not exist in Qt 4.7...):
def __init__(self):
self.colMapFromSource = {} # col source -> col proxy
self.colMapFromProxy = tuple() # col proxy -> col source
def set_column_to_display(self, column_to_display):
self.beginResetModel()
self.colMapFromProxy = tuple(column_to_display)
for i, x in enumerate(self.colMapFromProxy):
self.colMapFromSource[x] = i
self.endResetModel()
def flags(self, index):
return self.sourceModel().flags(self.mapToSource(index))
def setSourceModel(self, sourceModel):
# by default display all column with same order
self.set_column_to_display(
tuple(i for i in xrange(self.sourceModel().columnCount())))
return len(self.colMapFromProxy)
def mapFromSource(self, sourceIndex):
if sourceIndex.isValid():
if sourceIndex.column() in self.colMapFromSource:
return self.createIndex(sourceIndex.row(),
self.colMapFromSource[sourceIndex.column()])
def mapToSource(self, proxyIndex):
if proxyIndex.isValid():
return self.sourceModel().index(proxyIndex.row(),
self.colMapFromProxy[proxyIndex.column()])
class ModelColumnFilter(QtGui.QSortFilterProxyModel):
def __init__(self):
QtGui.QSortFilterProxyModel.__init__(self)
self.colMapFromSource = {} # col source -> col proxy
self.colMapFromProxy = tuple() # col proxy -> col source
def set_column_to_display(self, column_to_display):
self.beginResetModel()
self.colMapFromProxy = tuple(column_to_display)
for i, x in enumerate(self.colMapFromProxy):
self.colMapFromSource[x] = i
self.endResetModel()
def flags(self, index):
return self.sourceModel().flags(self.mapToSource(index))
def setSourceModel(self, sourceModel):
QtGui.QSortFilterProxyModel.setSourceModel(self, sourceModel)
# by default display all column with same order
self.set_column_to_display(
tuple(i for i in xrange(self.sourceModel().columnCount())))
def columnCount(self, parent=QtCore.QModelIndex()):
return len(self.colMapFromProxy)
def mapFromSource(self, sourceIndex):
if sourceIndex.isValid():
if sourceIndex.column() in self.colMapFromSource:
return self.createIndex(sourceIndex.row(),
self.colMapFromSource[sourceIndex.column()])
return QtCore.QModelIndex()
def mapToSource(self, proxyIndex):
if proxyIndex.isValid():
return self.sourceModel().index(proxyIndex.row(),
self.colMapFromProxy[proxyIndex.column()])
return QtCore.QModelIndex()
To copy to clipboard, switch view to plain text mode
So, whatever the number of view I'm using to display data in this model, they see only what I need (more over in the order I need).
This work great if I use it as is.
But if I want to sort columns, and use an other QSortFilterProxyModel like this:
mo = MyModel()
mf = ModelColumnFilter()
mf.setSourceModel(mo)
set_column_to_display([....])
mp.setSourceModel(mf)
view1.setModel(mp)
view1.setSortingEnabled(True)
view2.setModel(mp)
view2.setSortingEnabled(True)
mo = MyModel()
mf = ModelColumnFilter()
mf.setSourceModel(mo)
set_column_to_display([....])
mp = QtGui.QSortFilterProxyModel()
mp.setSourceModel(mf)
view1 = QtGui.QTreeView()
view1.setModel(mp)
view1.setSortingEnabled(True)
view2 = QtGui.QTreeView()
view2.setModel(mp)
view2.setSortingEnabled(True)
To copy to clipboard, switch view to plain text mode
view2 cause the application to crash.
I suppose it's a problem in my model (an index not very well formed ??).
Tell me if I'm doing it wrong, or How can I change this to make it work.
Thanks
Bookmarks