Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

ListView - How to refresh rows which content changed without slowdown?



  • In a ListView, I need to draw rows in which the position and size of the children components may change when a given event happens in the application, e.g when a button is clicked I need to move the location of an image contained in a row.

    However, after applying the change I needed to apply in my row, I tried to use the forceLayout() function in my qml code to refresh the tree, but this had no effect. As my ListView is linked to a c++ model, I tried to create the following c++ function in my model, and to call it from my qml code:

    void WQTListViewModel::refreshView()
    {
        emit layoutChanged();
    }
    

    This works, but have a cost. Indeed the refresh is very slow, and this isn't acceptable. I assume that the signal I use refresh or rebuild the entire tree, while I just need to refresh the visible rows (of course the change should also be applied to the not visible ones, but this may be done later, e.g when they become visible).

    I noticed that a TableView may resize its content without slowdown, so I assume that my refresh method is not the good one.

    So my questions are:

    1. How can I refresh only the rows visible on the screen, and certify that the not visible ones will be refreshed while become visible? And is this approach the good one?
    2. How can I correctly refresh my ListView component, and apply the changes in my rows, without slow down all my application?
    3. How does a TableView manage to change the size of its columns, and refresh all of its content on the fly, without any slowing down? Which signals are called under the hood?


  • In fact this issue was caused by an incorrect properties management in the component. As I used functions to set the properties values, and not local variables or model roles, the data changes were never detected, and thus the tree was never refreshed.

    I also used the following code:

    view.model.dataChanged(view.model.index(0, columnCount - 1), view.model.index(rowCount - 1, columnCount - 1));
    

    instead of:

    view.forceLayout()
    

    to ask the view to refresh when required.



  • In fact this issue was caused by an incorrect properties management in the component. As I used functions to set the properties values, and not local variables or model roles, the data changes were never detected, and thus the tree was never refreshed.

    I also used the following code:

    view.model.dataChanged(view.model.index(0, columnCount - 1), view.model.index(rowCount - 1, columnCount - 1));
    

    instead of:

    view.forceLayout()
    

    to ask the view to refresh when required.


  • Qt Champions 2018

    @jeanmilost said in ListView - How to refresh rows which content changed without slowdown?:

    view.model.dataChanged(view.model.index(0, columnCount - 1), view.model.index(rowCount - 1, columnCount - 1));

    So you are emiting dataChanged from QML? That seems like a bad practice, why can't you do that in the model?