ListView is updated wrong when custom QSortFilterProxyModel changes



  • Hi

    I'm using a QML ListView which has a C++ class that extends QSortFilterProxyModel as a model. The filter can show all elements from the original model or filter some of them, depending on the value of an attribute. I do this by defining my custom filterAcceptsRow() method.
    When the filter's attribute changes I have to reapply the filter and update the view manually. After some research I found out I can do this by emitting invalidateFilter() or invalidate() signals. Is this right?

    Now, Let's say as an example that the original model is just the first 10K numbers starting with 1. And that the filter, filters multiples of 100, so it shows 100, 200, 300, etc.

    Now, suppose that the filter is enabled and the current element at the top of the view is 4700. So I see: 4700, 4800, 4900, 5000, 5100, etc. Now, I change the filter's attribute so I have to reapply the filter and update the view manually:

    • If I emit invalidate() signal, the view always moves to the first element. So it shows 1, 2, 3...

    • If I emit invalidateFilter() signal, the view doesn't move so I see 4700, 4701, 4702, etc. This is the behavior I want...
      BUT sometimes the view is updated wrong, I see: unsorted elements, missing elements and/or blank elements!!!
      If I scroll the view and go back to the original position (which forces the view to update again) all elements are shown fine. So, I guess invalidateFilter() works fine but updates the view wrong.

    So my question is, How can I update the view correctly when the filter changes? Is this a bug?

    I have another question related with the previous one:
    If I define my ListView like this:
    @ ListView {
    anchors.fill: parent
    model: myModel //a qsortproxymodel from c++
    delegate: MyDelegate { myObject: object; }
    clip: true
    }@

    • If the top element is, let's say, 400 and I reapply the filter by emitting invalidateFilter() signal, the top element remains 400 but the next elements change. That's fine.
    • But if the top element is 100 (the first element when the filter is on) and I reapply the filter by emitting invalidateFilter() signal, the top element changes to 1 (the first element when the filter is off) instead of remain 100. Isn't it an strange and inconsistent behavior? Is it a bug?
      I can 'fix' this by setting
      @highlightRangeMode: ListView.StrictlyEnforceRange@

    but it has other effects that I don't want such as the behavior when I scroll to the last element.

    Thank you


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.