Order in which loading completes with GridView/ListView when using a Loader asynchronously in a delegate is reversed



  • I am using Qt 5.1.0 for a "Qt Quick Application" project (with QML and C++).

    I was trying to create a grid of images on my embedded device. I used a loader in the delegate for a smoother user experience. I noticed that the images would appear in a reverse order; the positions are correct, just the order in which they finish loading seems reversed - that is, I would see an empty window to start with, the images at indices 7, 6, 5 and 4 finish loading, although they are outside the visible area, then image at index 3 would appear at the bottom-most position in the window, followed by the image at index 2, then index 1 and finally the image at index 0.

    A simplified version of the QML code is posted below:

    @import QtQuick 2.1
    ListView
    {
    width: 120
    height: 400

    // Model to help populate the GridView
    model: 100
    
    delegate: Component
    {
        Loader
        {
            height: 100
            width: 150
    
            asynchronous: true
    
            sourceComponent: Component
            {
                Row
                {
                    spacing: 10
    
                    Text { text: index }
    
                    Image
                    {
                        height: 100
                        width: 100
                        source: "some_image.png"
                    }
                }
            }
            onStatusChanged: console.log( "Delegate " + index  + ": "
                                         + loaderStateNames[status] );
        }
    }
    
    property var loaderStateNames: [
        "Loader.Null",
        "Loader.Ready",
        "Loader.Loading",
        "Loader.Error"
    ]
    

    }
    @

    Output when using this in a "Qt Quick Application" project (with QML and C++):
    @
    Delegate 0: Loader.Loading
    Delegate 1: Loader.Loading
    Delegate 2: Loader.Loading
    Delegate 3: Loader.Loading
    Delegate 4: Loader.Loading
    Delegate 5: Loader.Loading
    Delegate 6: Loader.Loading
    Delegate 7: Loader.Loading
    Delegate 7: Loader.Ready
    Delegate 6: Loader.Ready
    Delegate 5: Loader.Ready
    Delegate 4: Loader.Ready
    Delegate 3: Loader.Ready
    Delegate 2: Loader.Ready
    Delegate 1: Loader.Ready
    Delegate 0: Loader.Ready
    @

    • Why do the loaders complete loading in the reverse order of their starting? Is this by design or am I missing something?
    • For a user looking at the screen, this behavior seems very odd, as they see items at the very end of the screen(possibly, just below the viewing area) show up first, while the images in the main viewing area appear only later.

    When I tried moving this QML code into a "Qt Quick 2 UI" project, and run with "QML Scene", it produced different results:

    Output when using this in a "Qt Quick 2 UI" project, produces the output below:
    @
    Delegate 0: Loader.Ready
    Delegate 1: Loader.Ready
    Delegate 2: Loader.Ready
    Delegate 3: Loader.Ready
    Delegate 4: Loader.Ready
    Delegate 5: Loader.Loading
    Delegate 6: Loader.Loading
    Delegate 7: Loader.Loading
    Delegate 7: Loader.Ready
    Delegate 6: Loader.Ready
    Delegate 5: Loader.Ready
    @

    • This behavior makes more sense to me; the items in the visible area appear first in the correct order.
    • It seems to have created items 0 through 4, which are in the viewing area, synchronously, I'm guessing, because I do not see the window until "Delegate 4: Loader.Ready" is printed out, and also because these loaders do not seem to go into the Loader.Loading state at all.
    • Thereafter, it seems to start loading a few additional items, but they again complete in the reverse order.
    • Why is there a difference in these usages for the same QML?




  • The order of creation is not guaranteed. In cases where the asynchronous loading does not take the same time per delegate, you could see any random order happening.

    The difference between qmlscene and qtquick2viewer is odd though, and could be caused by QTBUG-31203. If you prefer the qmlscene like behavior, try using this as your C++ application:

    @
    int main(int argc, char* argv[]) {
    QGuiApplication app(argc, argv);
    QQuickView v;
    v.setSource("main.qml");
    v.show();
    return app.exec();
    }
    @


Log in to reply
 

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