QSortFilterProxymodel sort weirdness
-
Hello all
I have implemented my own QAbstractTableModel and QSortFilterProxyModel. These are separate classes. The proxy filter is given a pointer to the table model and the proxy is then set as the model for the table view. Everything works as expected... except when sorting.
When I sort my table view the table is sorted according to the column and sort order (ascending vs descending). However, when I right click on my table view and pop open my context menu some items in the table view shuffle around and change place.
It seems like the QSortFilterProxyModel does some re-arrangement of sorted items based on the other non-primary column. This is all happening inside the QSortFIlterProxyModel somehow. I've debug printed the order of items before and after opening the context menu and it does indeed change.
Anyone what this is all about? Thanks
-
Hello all
I have implemented my own QAbstractTableModel and QSortFilterProxyModel. These are separate classes. The proxy filter is given a pointer to the table model and the proxy is then set as the model for the table view. Everything works as expected... except when sorting.
When I sort my table view the table is sorted according to the column and sort order (ascending vs descending). However, when I right click on my table view and pop open my context menu some items in the table view shuffle around and change place.
It seems like the QSortFilterProxyModel does some re-arrangement of sorted items based on the other non-primary column. This is all happening inside the QSortFIlterProxyModel somehow. I've debug printed the order of items before and after opening the context menu and it does indeed change.
Anyone what this is all about? Thanks
@SamiV123 said in QSortFilterProxymodel sort weirdness:
some items in the table view shuffle around and change place.
What pattern do you observe? Rows move or columns move? Are your rows still sorted after this or not? Are your primary keys indeed non-duplicated?
does some re-arrangement of sorted items based on the other non-primary column.
So that would mean it comes out with rows in a different and not-correctly-sorted order?
-
@SamiV123 said in QSortFilterProxymodel sort weirdness:
some items in the table view shuffle around and change place.
What pattern do you observe? Rows move or columns move? Are your rows still sorted after this or not? Are your primary keys indeed non-duplicated?
does some re-arrangement of sorted items based on the other non-primary column.
So that would mean it comes out with rows in a different and not-correctly-sorted order?
Hi,
How did you implement your custom QSortFilterProxyModel ? What about your other model ?
-
@JonB The rows move. Primary keys are duplicated.
It looks like the sorted data is not stable, i.e. the relative order items sorted by the same key changes. But why does it change suddenly on context menu open? (I'm reacting to customContextMenuRequested signal and build a QMenu which I then exec())
Here is the data in the QTableView after I've clicked on the Type column and the data has been sorted into ascending order by type. The underlying data model provides the data as a QString.

This is how the data shuffles around when I open my context menu.

-
@JonB The rows move. Primary keys are duplicated.
It looks like the sorted data is not stable, i.e. the relative order items sorted by the same key changes. But why does it change suddenly on context menu open? (I'm reacting to customContextMenuRequested signal and build a QMenu which I then exec())
Here is the data in the QTableView after I've clicked on the Type column and the data has been sorted into ascending order by type. The underlying data model provides the data as a QString.

This is how the data shuffles around when I open my context menu.

@SamiV123
Indeed, as suspected you are sorting on some column allowing duplicates and your sort is unstable/non-deterministic.Therefore potentially order could change at any time. For whatever reason a context menu request causes an update/re-sort (presumably you could discover this is the case with debug messages), and perhaps calls it slightly differently so that it delivers a different order.
The moral is you had better go for a stable sort! One way might be to have your sort on a non-PK column with duplicates look at the PK column as well as secondary sort if/when the comparer is called on sort column with two elements whose secondary sort column values compare equal.
-
@SamiV123
Indeed, as suspected you are sorting on some column allowing duplicates and your sort is unstable/non-deterministic.Therefore potentially order could change at any time. For whatever reason a context menu request causes an update/re-sort (presumably you could discover this is the case with debug messages), and perhaps calls it slightly differently so that it delivers a different order.
The moral is you had better go for a stable sort! One way might be to have your sort on a non-PK column with duplicates look at the PK column as well as secondary sort if/when the comparer is called on sort column with two elements whose secondary sort column values compare equal.
@JonB Thanks for the reply,
yeah this is probably what is happening indeed. The thing is though the sort is implemented/provided by the QSortFilterProxyModel class provided by Qt5.
My derived class only implements the filterAcceptsRow function, so I'm not really sure what I can do in my code for the sort stability.
Should I look at implementing the lessThan function?
-
@JonB Thanks for the reply,
yeah this is probably what is happening indeed. The thing is though the sort is implemented/provided by the QSortFilterProxyModel class provided by Qt5.
My derived class only implements the filterAcceptsRow function, so I'm not really sure what I can do in my code for the sort stability.
Should I look at implementing the lessThan function?
@SamiV123 said in QSortFilterProxymodel sort weirdness:
Should I look at implementing the lessThan function?
Absolutely! I thought you already had. That is where I meant to add the "sort with PK as secondary on other columns which are not unique and allow duplicate values".
I don't know whether the behaviour you see is a "feature" of your Qt version or whether there is something going on in your code or even if there is something funny going on with context menu code. Because this would be waiting to bite anyone who naively assumes they can sort on duplicate columns without worrying about rearrangement, and we might have had more posts to that effect here but I have not seen any previously. Or the docs might have mentioned/warned about this.
I suggest you try the
lessThan()with secondary on PK to verify the rearranging goes away and hence it is the cause. Then maybe someone else might like to comment on whether this behaviour is unintended or not. -
S SamiV123 has marked this topic as solved on