Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QSortFilterProxyModel filtering complete signal

I'm using a custom QSortFilterProxyModel to implement custom filtering for QTableView by overriding filterAcceptsRow(). How can my application be notified when I change the filtering criteria and after filterAcceptsRow() is applied on the whole table?

Basically, I want to get a list of the visible item after filtering is applied, currently I calculate this list by a custom function I've implemented in my model that iterates on the rows and get a list of visible rows. This is inefficient as two calls to this function will yield the same results if no filtering action occurred in between.

like image 509
Mohamed Avatar asked Apr 23 '15 13:04

Mohamed


2 Answers

All models should emit layoutAboutToBeChanged() and layoutChanged(), before and after they are sorted, filtered, or changed in any other way that could affect the view.

like image 85
ekhumoro Avatar answered Nov 14 '22 07:11

ekhumoro


from my observations (in Qt 4.8), the layout*() signals will fire when sorting the proxy model, but not if you implement filtering. also the docs explicitly refer to the order of items that are meant by these signals, and filtering naturally doesn't change the order but affects rows only.

in this case only the rows*(...) signals (inserted, removed, etc.) will fire, depending on what the filter just did. the downside is, if the filter is applied recursively (usually it is), these signals will fire in masses, so will not be useful to tie to a single resulting action.

to overcome this you could call invalidate() after setting filters (not invalidateFilter btw, since it also won't fire the layout signals).

since this re-applies filtering and sorting (the latter wouldn't be necessary when filtering, but can't be avoided), the layout*()signals will fire after both did end.

but then it would be better to handle the filter string/regExp/whatever on your own instead using the base methods (like setFilterFixedString(...)) to set them, to at least avoid filtering twice - not much overhead anyway if you already re-implemented the filterAcceptsRow(...).

an alternative way would be to emit an own signal when setting sorting or filter, and connecting to it by using Qt::QueuedConnection to make sure it is executed after filtering did end. that's what i finally did (to update a register of the table) and as far i can tell it works like expected.

like image 8
t_3 Avatar answered Nov 14 '22 06:11

t_3