[SOLVED] QML listview resetting to start when data is updated



  • I have a QML listview containing a list of possible items to download. Once the download is started the download process is updated via a signal which works fine. The problem is that each time the data is updated the list cursor is set to the top so you are happily scrolling down then rudely taken back to the top of the list - which is especially bad if the download is progressing quickly. The data is coming from c++ via

    @
    getViewer()->rootContext()->setContextProperty("model", listData)
    @

    I have something similar in QML with the data being updated by the QML going and getting the data to re assemble the list itself but I was wondering if there was any way to do it from the c++?



  • Take a look at this:

    http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginInsertRows

    Then you can do something like this:

    @void ListModel::addListItem(const ListItem &item)
    {
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_list << item;
    endInsertRows();
    }@

    m_List is just a list of ListItem objects. The point here is that you will not replace the model each time with a new one, but you will just update the one you have.



  • Brilliant thank you I will try that.

    Is there a cure for my list always starting at the first item? Ideally it should not moving down the list until the down arrow is pressed (this is for blind users) so they skip they end up skipping the info for the first item and move onto item 2. I have tried setting my index to -1 in the component completed but it still highlights the first item (rather than no items being highlighted and the down arrow activating item 1). It wraps around too which is not what is required - both problems seem like they should be so easy to implement but I am having no joy at all!



  • You could probably add another item over the listview and set focus to that. Then use, KeyNavigation.down: listview instead. Or you could use Keys.onDownPressed and do more logic there.

    http://qt-project.org/doc/qt-4.8/qml-keys.html#onDownPressed-signal

    But you still need to set the currentIndex to -1 in the list.

    This code works for me (but Im not sure that I understand your problem:):

    @
    Rectangle{
    id: rect
    width: parent.width
    height: 30
    focus: true
    KeyNavigation.down: listView
    color: focus ? "blue" : "red"
    }

    ListView{
        id: listView
        anchors.top: rect.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        currentIndex: -1
    
        model: listModel
        delegate: listDelegate
    
        onFocusChanged: {
            if(focus){
                currentIndex = 0;
            }
            else{
                currentIndex = -1;
            }
        }
    
    }
    

    @



  • My code is below. When the list loads it does not have any items highlighted. Hit the down key and the c++ code receives index 0 but the listview highlights the second item rather then the first and it just goes belly up from there.

    @
    ListView
    {
    anchors.centerIn: parent
    id: list
    model: menuModel
    clip: true

           width: parent.width // Minimum width
           height: ((defaultEntryHeight * (list.count + 1)) + defaultMargin) > parent.height
                   ? parent.height - defaultMargin : (defaultEntryHeight * (list.count + 1))
    
           onWidthChanged: if(width > menu.width) width = menu.width
    
           currentIndex: -1
           onFocusChanged:
           {
               if(focus)
               {
                   currentIndex = 0;
               }
               else
               {
                   currentIndex = -1;
               }
           }
    
            header: Rectangle
            {
                width: parent.width
                height: defaultEntryHeight
                color: "#2A51A3"
    
                Text
                {
                   id: headerText
                   anchors.centerIn: parent
                   text: listTitle
                   font.pointSize: fontPointSize
                   color: "white"
                }
            }
    
            delegate: listDelegate
            focus: true
    
            add: Transition
            {
                NumberAnimation { properties: "x,y" }
            }
    
            Keys.onReleased:
            {
                QMLManager.handleKey(event.key, currentIndex)
            }
    
            Keys.onPressed:
            {
               if(event.key === Qt.Key_F8 || event.key === Qt.Key_Home || event.key === Qt.Key_Escape
                        || event.key === Qt.Key_Return || event.key ===Qt.Key_Enter
                        || (event.key >= Qt.Key_1 && event.key <= Qt.Key_9)
                        || event.key === Qt.Key_Up || event.key === Qt.Key_Down)
    
                {
    
                    QMLManager.handleKey(event.key, currentIndex)
    
                }
            }
        }
    

    @



  • OMG it works....well partially. I just noticed the KeyNavigation.down line of code and now I get the first item in the list highlighted - the c++ is getting -1 but that is easy to sort. Now I just have to work out how get the up key working.......... thank you so much. This seemed like such a simple issue and has been very frustrating that it was not working.



  • OK, no it did not work - the index getting to the c++ and the visual item got out of sync quickly if you did multiple up/downs. The listview knows it has 3 items so lets the index go up to 3 even though you started at -1 which is just pants so (when there are 3 items) index could by out by up to 2. My final solution was to use Keys.onReleased rather than onPressed to get a sensible index.

    Phew!


Log in to reply
 

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