Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. ListView issue when updated (current index set to 0)
Forum Updated to NodeBB v4.3 + New Features

ListView issue when updated (current index set to 0)

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 3 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mickael 22
    wrote on 7 Apr 2021, 14:41 last edited by
    #1

    Hi all,
    I meet an issue with listView when the model is updated from C++.
    After each update from C++, the current index is set to 0 and the view return to beginning of it !
    In the C++ side, the model exposed is declared like this :

    Q_PROPERTY(QList<QObject*> debugList READ getDebugList NOTIFY debugListChanged)
    

    in qml :

     Component {
                        id: nameDelegate
                        Item {
                            id: delegateItem
                            height: ListView.isCurrentItem ? 25 : textDebug.height
                            width:debugRx.width
                            Behavior on height {
                                NumberAnimation {
                                    duration: 750
                                    easing.type: "InOutQuint"
                                }
                            }
                            Text {
                                id:textDebug
                                text: model.modelData.data
                                color: model.modelData.color
                                width: debugRx.width
                                //height: 20
                                lineHeight: 15
                                lineHeightMode:  Text.FixedHeight
                                scale: parent.height/height
                                transformOrigin: Item.Left
                                wrapMode: Text.WordWrap
                                font{
                                    family: "arial"
                                    pixelSize:16
                                }
                            }
                        }
                    }
    
                    ListView {
                        id:listViewDebug
                        snapMode: ListView.SnapOneItem
                        property string name: "listeDebug"
                        property bool scrollDebugAuto: true
                        property int scrollDebugIndex: 0
                        bottomMargin: 5
                        anchors.fill: parent
                        anchors.topMargin: 5
                        anchors.bottomMargin: 5
                        anchors.leftMargin: 2
                        anchors.rightMargin: 2
                        clip:true
                        model:device.debugList
                        focus:true
                        delegate: nameDelegate
                        ScrollBar.vertical: ScrollBar{
                            id:scrollBarDebug
                        }
    
                        highlight: Rectangle {
                            width: listViewDebug.width;
                            border.color: "gray"
                            border.width: 2
                            color : "green"
                            opacity: 0.3
                            radius:5
                            Behavior on y {
                                SpringAnimation {
                                    spring: 3
                                    damping: 0.2
                                }
                            }
                        }
                        highlightFollowsCurrentItem: true
                        //highlightRangeMode : ListView.StrictlyEnforceRange
                        currentIndex: scrollDebugAuto ? listViewDebug.count-1 : scrollDebugIndex
                        onCurrentIndexChanged:{
                            console.log("current index update :"+currentIndex)
                        }
                        onModelChanged: {
                            console.log("current index :"+currentIndex);
                            console.log("save index : "+scrollDebugIndex)
                        }
                        Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning)
    
                    }
                }
    

    When the property scrollDebugAuto is true it work fine (the view stay et end of the listView) but when it false the view goes to beginning (current index : 0)
    false--> i 'm trying to add a functionality to disable the list update continuously when the user click to a button

                    CheckBox {
                        id: checkBox
                        text: "\uf0c1"
                        checked: true
                        onCheckedChanged:
                        {
                            if(checked)
                                listViewDebug.scrollDebugAuto=true
                            else
                            {
                                listViewDebug.scrollDebugAuto=false
                                listViewDebug.scrollDebugIndex=listViewDebug.count-1
                                console.log("scroll debug index : "+listViewDebug.scrollDebugIndex)
                            }
                        }
                    }
    

    That's strange is when the model is updated from C++, the listView index is set to 0 !
    When the scrollDebugAuto is true i have this on the log :

    qml: current index update :52
    qml: current index update :0
    qml: current index update :52
    qml: current index :53
    qml: save index : 0

    when is false

    qml: current index update :0
    qml: current index :89
    qml: save index : 72

    we can see that the current index is set to 0 during C++ model update .
    Do you have an idea how i can resolve this ?

    K 1 Reply Last reply 7 Apr 2021, 15:11
    0
    • M Mickael 22
      7 Apr 2021, 14:41

      Hi all,
      I meet an issue with listView when the model is updated from C++.
      After each update from C++, the current index is set to 0 and the view return to beginning of it !
      In the C++ side, the model exposed is declared like this :

      Q_PROPERTY(QList<QObject*> debugList READ getDebugList NOTIFY debugListChanged)
      

      in qml :

       Component {
                          id: nameDelegate
                          Item {
                              id: delegateItem
                              height: ListView.isCurrentItem ? 25 : textDebug.height
                              width:debugRx.width
                              Behavior on height {
                                  NumberAnimation {
                                      duration: 750
                                      easing.type: "InOutQuint"
                                  }
                              }
                              Text {
                                  id:textDebug
                                  text: model.modelData.data
                                  color: model.modelData.color
                                  width: debugRx.width
                                  //height: 20
                                  lineHeight: 15
                                  lineHeightMode:  Text.FixedHeight
                                  scale: parent.height/height
                                  transformOrigin: Item.Left
                                  wrapMode: Text.WordWrap
                                  font{
                                      family: "arial"
                                      pixelSize:16
                                  }
                              }
                          }
                      }
      
                      ListView {
                          id:listViewDebug
                          snapMode: ListView.SnapOneItem
                          property string name: "listeDebug"
                          property bool scrollDebugAuto: true
                          property int scrollDebugIndex: 0
                          bottomMargin: 5
                          anchors.fill: parent
                          anchors.topMargin: 5
                          anchors.bottomMargin: 5
                          anchors.leftMargin: 2
                          anchors.rightMargin: 2
                          clip:true
                          model:device.debugList
                          focus:true
                          delegate: nameDelegate
                          ScrollBar.vertical: ScrollBar{
                              id:scrollBarDebug
                          }
      
                          highlight: Rectangle {
                              width: listViewDebug.width;
                              border.color: "gray"
                              border.width: 2
                              color : "green"
                              opacity: 0.3
                              radius:5
                              Behavior on y {
                                  SpringAnimation {
                                      spring: 3
                                      damping: 0.2
                                  }
                              }
                          }
                          highlightFollowsCurrentItem: true
                          //highlightRangeMode : ListView.StrictlyEnforceRange
                          currentIndex: scrollDebugAuto ? listViewDebug.count-1 : scrollDebugIndex
                          onCurrentIndexChanged:{
                              console.log("current index update :"+currentIndex)
                          }
                          onModelChanged: {
                              console.log("current index :"+currentIndex);
                              console.log("save index : "+scrollDebugIndex)
                          }
                          Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning)
      
                      }
                  }
      

      When the property scrollDebugAuto is true it work fine (the view stay et end of the listView) but when it false the view goes to beginning (current index : 0)
      false--> i 'm trying to add a functionality to disable the list update continuously when the user click to a button

                      CheckBox {
                          id: checkBox
                          text: "\uf0c1"
                          checked: true
                          onCheckedChanged:
                          {
                              if(checked)
                                  listViewDebug.scrollDebugAuto=true
                              else
                              {
                                  listViewDebug.scrollDebugAuto=false
                                  listViewDebug.scrollDebugIndex=listViewDebug.count-1
                                  console.log("scroll debug index : "+listViewDebug.scrollDebugIndex)
                              }
                          }
                      }
      

      That's strange is when the model is updated from C++, the listView index is set to 0 !
      When the scrollDebugAuto is true i have this on the log :

      qml: current index update :52
      qml: current index update :0
      qml: current index update :52
      qml: current index :53
      qml: save index : 0

      when is false

      qml: current index update :0
      qml: current index :89
      qml: save index : 72

      we can see that the current index is set to 0 during C++ model update .
      Do you have an idea how i can resolve this ?

      K Offline
      K Offline
      KroMignon
      wrote on 7 Apr 2021, 15:11 last edited by
      #2

      @Mickael-22 said in ListView issue when updated (current index set to 0):

      Do you have an idea how i can resolve this ?

      AFAIK, this is the normal behavior when using QList<Object *>() or QStringList() as model, because each model update will generate a full new model.
      If you wan't a smooth update, you have to use QAbstractItemModel , cf. https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      M 1 Reply Last reply 7 Apr 2021, 15:44
      0
      • K KroMignon
        7 Apr 2021, 15:11

        @Mickael-22 said in ListView issue when updated (current index set to 0):

        Do you have an idea how i can resolve this ?

        AFAIK, this is the normal behavior when using QList<Object *>() or QStringList() as model, because each model update will generate a full new model.
        If you wan't a smooth update, you have to use QAbstractItemModel , cf. https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html

        M Offline
        M Offline
        Mickael 22
        wrote on 7 Apr 2021, 15:44 last edited by
        #3

        @KroMignon Thanks for this explanations, it's more clear now.
        I will have a look on QAbstractItemModel class, it just pity to add more complexity with this class to just keep list current index to it's value !

        K 1 Reply Last reply 7 Apr 2021, 16:26
        0
        • M Mickael 22
          7 Apr 2021, 15:44

          @KroMignon Thanks for this explanations, it's more clear now.
          I will have a look on QAbstractItemModel class, it just pity to add more complexity with this class to just keep list current index to it's value !

          K Offline
          K Offline
          KroMignon
          wrote on 7 Apr 2021, 16:26 last edited by
          #4

          @Mickael-22 Yes QAbstractItemModel is not easy to use.

          I use since many years now a template class create by Thomas Boutroue which creates an QAbstractListModel by introspection of the base QObject.
          Take a look at Qt QML Models and Qt SuperMacros.

          Here are some explanations at Qt World Summit 2015:
          https://resources.qt.io/videos/qtws15-lightning-talk-a-new-way-for-creating-qml-models-from-c-thomas-boutroue

          Perhaps this could help you.

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          M 1 Reply Last reply 9 Apr 2021, 13:45
          1
          • jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on 7 Apr 2021, 20:25 last edited by
            #5

            This is an undocumented behavior of ListView. When the model is changed, currentIndex is set to 0, or -1 if the model if the empty.

            https://code.woboq.org/qt5/qtdeclarative/src/quick/items/qquickitemview.cpp.html#239:

            if (d->model) {
                    ...
                    if (isComponentComplete()) {
                        ...
                        setCurrentIndex(d->model->count() > 0 ? 0 : -1);
            

            If you have the option, updating the model rather than changing to a new one is probably a better method.

            Asking a question about code? http://eel.is/iso-c++/testcase/

            1 Reply Last reply
            1
            • K KroMignon
              7 Apr 2021, 16:26

              @Mickael-22 Yes QAbstractItemModel is not easy to use.

              I use since many years now a template class create by Thomas Boutroue which creates an QAbstractListModel by introspection of the base QObject.
              Take a look at Qt QML Models and Qt SuperMacros.

              Here are some explanations at Qt World Summit 2015:
              https://resources.qt.io/videos/qtws15-lightning-talk-a-new-way-for-creating-qml-models-from-c-thomas-boutroue

              Perhaps this could help you.

              M Offline
              M Offline
              Mickael 22
              wrote on 9 Apr 2021, 13:45 last edited by Mickael 22 4 Sept 2021, 13:55
              #6

              @KroMignon Thanks a lot !

              @jeremy_k
              in the C++ code i just emit a signal that the list changed like this :

                  m_debugList.append(new BleData(data,color,this));
                  emit debugListChanged();
              
              class BleData : public QObject
              {
                  Q_OBJECT
              
              public:
                  explicit BleData(QObject *parent = nullptr);
                  BleData(QString data,QString color = "black",QObject *parent = nullptr);
              
                  Q_PROPERTY(QString data READ getData NOTIFY dataChanged)
                  Q_PROPERTY(QString color READ getColor NOTIFY colorChanged)
              
              signals:
              
                  void dataChanged(QString data);
                  void colorChanged(QString color);
              
              public slots:
                  QString getData() const;
                  QString getColor() const;
                  void addData(QString data,QString color="black");
              
              private :
                  QString m_data;
                  QString m_color;
              };
              

              I don't know how to proceed in another way

              jeremy_kJ 1 Reply Last reply 10 Apr 2021, 07:56
              0
              • M Mickael 22
                9 Apr 2021, 13:45

                @KroMignon Thanks a lot !

                @jeremy_k
                in the C++ code i just emit a signal that the list changed like this :

                    m_debugList.append(new BleData(data,color,this));
                    emit debugListChanged();
                
                class BleData : public QObject
                {
                    Q_OBJECT
                
                public:
                    explicit BleData(QObject *parent = nullptr);
                    BleData(QString data,QString color = "black",QObject *parent = nullptr);
                
                    Q_PROPERTY(QString data READ getData NOTIFY dataChanged)
                    Q_PROPERTY(QString color READ getColor NOTIFY colorChanged)
                
                signals:
                
                    void dataChanged(QString data);
                    void colorChanged(QString color);
                
                public slots:
                    QString getData() const;
                    QString getColor() const;
                    void addData(QString data,QString color="black");
                
                private :
                    QString m_data;
                    QString m_color;
                };
                

                I don't know how to proceed in another way

                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on 10 Apr 2021, 07:56 last edited by
                #7

                @Mickael-22 said in ListView issue when updated (current index set to 0):

                @KroMignon Thanks a lot !

                @jeremy_k
                in the C++ code i just emit a signal that the list changed like this :

                    m_debugList.append(new BleData(data,color,this));
                    emit debugListChanged();
                

                That's the entire problem. Emitting the change signal for the list of QObjects says the entire list has changed, and should be treated as a new model.

                The item models that @KroMignon refers to have signals to indicate changes within the model. If implementing a new QAbstractItemModel sounds like too much work, using a QStandardItemModel, or a QML ListView might work. QStringListView could also, with some changes to the delegate.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Mickael 22
                  wrote on 12 Apr 2021, 07:11 last edited by
                  #8

                  Thanks for this precisions.
                  i will have a look on the different options and let you know the more convenient way i will use

                  1 Reply Last reply
                  0

                  1/8

                  7 Apr 2021, 14:41

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved