PDA

View Full Version : Using QSortFilterProxyModel



Jennie Bystrom
6th December 2007, 10:32
Hi,

I need some help with the use of the QSortFilterProxyModel. I have searched the documentation and here on the forum but haven't been able to find any similar issues.

This is what I want to do:

I have two table views that should visualize the same data. One is a filtered version of the other so it will not show all columns. I call them collapsedView and expandedView. Both are QTableView.

To accomplish this filtering functionality I have added a QSortFilterProxyModel between the sourceModel (of type QAbstractTableModel) and the collapsedView:




QTableView* collapsedView = new QTableView();
QTableView* expandedView = new QTableView();

SourceModel* sourceModel = new SourceModel(); // SourceModel is derived from QAbstractTableModel
FilterModel* filterModel = new FilterModel(); // FilterModel is derived from QSortFilterProxyModel
filterModel->setSourceModel(sourceModel);

collapsedView->setModel(filterModel);
expandedView->setModel(sourceModel);



This works fine and both the views behave as I want.
But I also want to be able to sort the tables by clicking on the column headers. And I also want both the views to be sorted the same way regardless in what view I click the header. If I sort the items in one view, the other view should rearrange its rows in the same way.

So I tried to add another QSortFilterProxyModel between the source model and the filter model that should handle the sorting for both the views:




SourceModel* sourceModel = new SourceModel();
SortModel* sortModel = new SortModel(); // SortModel is derived from QSortFilterProxyModel
sortModel->setSourceModel(sourceModel);
FilterModel* filterModel = new FilterModel();
filterModel->setSourceModel(sortModel);

collapsedView->setModel(filterModel);
expandedView->setModel(sortModel);



I also reimplemented the lessThan-method in the sortModel.
I am now able to sort according to columns by clicking on the header, but only the view that I click in are sorted. When I switch to the other view, this one is not affected by the sort.
It seems that the sorting only affects the view that the sorting was called from. How can I get the other view to be aware that it should change it layout?
Tried to emit the layoutChanged signal, but it doesn't seem to help.

Is this the right approach? Should I implement the sort-function on the source model instead? Thought I wouldn't have to do that since there is this proxy model for sorting.

I'd be grateful for any input!

jpn
6th December 2007, 10:42
I have two table views that should visualize the same data. One is a filtered version of the other so it will not show all columns. I call them collapsedView and expandedView. Both are QTableView.
You don't need a proxy model to hide columns if that's all difference between them. You can use QTableView::setColumnHidden().



QTableView* collapsedView = new QTableView();
QTableView* expandedView = new QTableView();

SourceModel* sourceModel = new SourceModel();
FilterModel* filterModel = new FilterModel();
filterModel->setSourceModel(sourceModel);

collapsedView->setModel(filterModel);
expandedView->setModel(filterModel);

collapsedView->setColumnHidden(2, true); // hide for example second column

This way sorting should work correctly out of the box in both views.

Jennie Bystrom
6th December 2007, 11:17
Ah, what a simple solution to my problem!
Thanks a lot! :)

Just for curiosity, how would you go about do this if the filter was a bit more advanced and you would have to use the proxy model for the filter? As far as I know, this is all I need for now, but that may change in the future.

jpn
6th December 2007, 11:28
I guess in that case you would have to connect to both table's horizontal header's signal QHeaderView::clicked() and apply the corresponding sorting column and order to the other table.