Triggering a QSortFilterProxyModel to refresh sort

Noob at KDE dev here. I’m having a go at fixing #458254 which I’ve run into myself. The report is a little inaccurate: the pref isn’t supposed to hide completed to-dos, merely sort them differently. The problem is currently you must either restart KOrganizer or toggle flat/tree view to see the preference change take effect so from the user’s perspective it looks broken.

I’ve tracked the configuration tracking down to TodoView::updateConfig in PIM EventViews and have managed to make a change that works, but I’m not happy with it.

void TodoView::updateConfig()
    if (!mSidebarView && mQuickSearch) {

    if (mQuickAdd) {

    qCWarning(CALENDARVIEW_LOG) << "State of the sort thing "
        << preferences()->sortCompletedTodosSeparately();

    // crashes inside QSortFilterProxyModel, with or without the sModels check

    // works, but you can see the view get recreated (scroll position changes)
    // even if you were changing some unrelated preference
    if (sModels && sModels->todoModel) {


Somehow I need to refresh the view so that it will call TodoViewSortFilterProxyModel::lessThan again and re-check mPreferences->sortCompletedTodosSeparately(). It seems like invalidate() was the wrong approach. Does anyone have any ideas where I should apply pressure to make this happen cleanly? Thanks!

(Originally posted on but it’s receding in the scrollback)

I remember having to butt heads against this recently, could it be QSortFilterProxyModel::sort that you’re looking for?

Thanks! Mystery solved: it was invalidate() I wanted all along. I just got a bit bamboozled in the debugger which was trying to tell me that mProxyModel was null in one case. sort() would have been the way to go if not using a dynamic sort filter, as summarised in this SO answer.