QML "infinite" ListView



  • Hi all :)
    As a newbie, I'm tring to make things way more difficult to those I can be able to do, so will need help to make lots of things... xD

    What I would like to know/do is a listview with an "infinite" number of element, as for example could be that of the QML Store client for applications: once you reach the end of the app list, new element are loaded and added to the list itself.

    What I am doing is a blog app, so the idea is to load articles (titles) on a listview using a XmlListModel, and once the user reach the end of the list, dynamically load new articles to show. Is there an easy or practible way to do this? Or is it better to find other ways in order to do this sort of pagination? :P

    Thanks all :)



  • I don't think that with XmlListModel it can be done, but if you reimplement your own listmodel, with a method that load new elements, this should be easy.

    Reimplement a QAbstractListModel by implementing rowCount(), and data(). (More in the docs).

    You can also add slots that can be called inside QML to load more elements.



  • Ok, so... I will try to investigate on this solution, let's see what sort of mess I can make... :P

    PS: any idea on how to detect that the user has scroll to the end of the list? :)



  • this could be done by using the valueChanged signal of the scroll bar
    [quote author="Ices_Eyes" date="1340693731"]PS: any idea on how to detect that the user has scroll to the end of the list? :)[/quote]



  • [quote author="raaghuu" date="1340694509"]this could be done by using the valueChanged signal of the scroll bar
    [/quote]

    Any more hint about the scroll bar? :P



  • [quote author="Ices_Eyes" date="1340694878"]
    [quote author="raaghuu" date="1340694509"]this could be done by using the valueChanged signal of the scroll bar
    [/quote]

    Any more hint about the scroll bar? :P[/quote]

    I think I found another solution... Could this be acceptable? :)
    On the ListView element:
    @onMovementEnded: {
    if(atYEnd) {
    console.log("End of list!");
    }
    }@



  • QScrollBar... the QWidgets which implement scroll bar automatically inherit horizontal/verticalScrollBar() functions from QAbstractScrollArea...these return QScrollBar* of the widget... QScrollBar emits valueChanged(int) signal which can be checked with QScrollBar::maximum(), inherited from QAbstractSlider. maximum() gives the maximum value of the slider(i.e., the end value)... you can connect this signal to a slot which loads new content...this would definitely work(probably with a little tweaking and the help from docs)



  • oh QML...sorry...my bad...cancel the previous posts



  • although there would be a similar mechanism in qml too, i'm sure... take a look at the docs...you'll find it



  • [quote author="raaghuu" date="1340696534"]oh QML...sorry...my bad...cancel the previous posts[/quote]

    LoL! Well, ok... In fact I was thinking on how to do that without C++ code... :P



  • you could use the currentIndex property of ListView and when it reaches the end, you could add items to the list...
    P.S. i just started qml a few days back(though i've been at Qt-c++ for quite some time now), so i don't know much...but this seems like a solution...do tell if this works :)



  • I think I manage to make all work like I want :P

    Advice or comment are really appreciated :)

    @
    UpdatableXmlListModel.qml
    import QtQuick 1.1

    ListModel {
    id: root
    default property alias roles: xmlListModel.roles
    property alias source: xmlListModel.source
    property alias query: xmlListModel.query
    property alias namespaceDeclarations: xmlListModel.namespaceDeclarations

    property alias status: xmlListModel.status
    
    function push(item) {
        append(item);
    }
    
    property variant __xmlListModel: XmlListModel {
        id: xmlListModel
    
        property variant keys: []
        onSourceChanged: {
            console.debug(source)
        }
    
        function appendItem(index, count) {
            for (var i = 0; i < count; i++) {
                var item = get(i + index);
                    push(item);
            }
        }
    
        onItemsInserted: appendItem(index, count)
    }
    
    Component.onCompleted: {
        var keys = new Array()
        for (var i = 0; i < roles.length; ++i) {
            if (roles[i].isKey) {
                keys.push(roles[i].name);
            }
        }
        xmlListModel.keys = keys;
    }
    

    }@

    @NewsList.qml

    ....

    UpdatableXmlListModel {
    id: newsModel
    query: "/root/item"

    XmlRole {
        name: "id"
        query: "id/string()"
    }
    XmlRole {
        name: "title"
        query: "title/string()"
    }
    XmlRole {
        name: "thumb"
        query: "thumb/string()"
    }
    XmlRole {
        name: "pubDate"
        query: "pubDate/string()"
    }
    
    onStatusChanged: {
        ....
    }
    

    }@

    :D


Log in to reply
 

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