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. Changing of C++ model doesn't update QML ListView
QtWS25 Last Chance

Changing of C++ model doesn't update QML ListView

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
listviewqabstractlistmo
10 Posts 6 Posters 6.1k Views
  • 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.
  • F Offline
    F Offline
    FOXLISIN
    wrote on last edited by
    #1

    Hi. During the process of moving from QWidgets to QML I faced with the next problem: changing of C++ model doesn't update QML ListView. But on QWidgets all works as expected, i.e: emitting of dataChanged(index(0), index(rowCount())) signal updates my QListView from QWidgets.

    My C++ model gets data through "Dispatcher" class, which returns different count of elements and values for roles for different ID, for example:

    rowCount(...) method of my model looks like this:

    int ChatModel::rowCount( const QModelIndex &theIndex ) const
    {
        return _ChatDispatcher->messageCount();
    }
    

    And here is messageCount() method of my Dispatcher: _DialogID - field of Dispatcher class

    int ChatDispatcher::messageCount()
    {
        return GetMessagesCount( _DialogID );
    }
    

    And when i change _DialogID i want to redraw the ListView by emitting dataChanged(index(0), index(rowCount())) signal. But for QML ListView it doesn't work.

    I've tryed this instead of dataChanged(..):

    beginResetModel();
    endResetModel();
    

    It works, but very slowly. Maybe you advise me something useful?

    p3c0P A 2 Replies Last reply
    0
    • D Offline
      D Offline
      dynamo72
      wrote on last edited by
      #2

      Maybe this helps: if the number of rows changes, you have to call also QAbstractModel::beginInsertRows() and endInsertRows() - these take care of emitting the signals like rowsAboutToBeInserted() etc. - and these seem to be important for QML view updates.

      1 Reply Last reply
      0
      • F FOXLISIN

        Hi. During the process of moving from QWidgets to QML I faced with the next problem: changing of C++ model doesn't update QML ListView. But on QWidgets all works as expected, i.e: emitting of dataChanged(index(0), index(rowCount())) signal updates my QListView from QWidgets.

        My C++ model gets data through "Dispatcher" class, which returns different count of elements and values for roles for different ID, for example:

        rowCount(...) method of my model looks like this:

        int ChatModel::rowCount( const QModelIndex &theIndex ) const
        {
            return _ChatDispatcher->messageCount();
        }
        

        And here is messageCount() method of my Dispatcher: _DialogID - field of Dispatcher class

        int ChatDispatcher::messageCount()
        {
            return GetMessagesCount( _DialogID );
        }
        

        And when i change _DialogID i want to redraw the ListView by emitting dataChanged(index(0), index(rowCount())) signal. But for QML ListView it doesn't work.

        I've tryed this instead of dataChanged(..):

        beginResetModel();
        endResetModel();
        

        It works, but very slowly. Maybe you advise me something useful?

        p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #3

        @FOXLISIN Can you post the code where you call dataChanged ?

        157

        1 Reply Last reply
        0
        • F Offline
          F Offline
          FOXLISIN
          wrote on last edited by
          #4

          @p3c0

          I call it by click on Qml button:

          RoundedButton {
                  id: sendButton;
          
                  text: "send";
          
                  anchors {
                      right: parent.right;
                      bottom: parent.bottom;
                      rightMargin: dp(15);
                      bottomMargin: dp(15);
                  }
          
                  onClicked: sendMessage();
              }
          
              function sendMessage()
              {
                  if( messageInput.text !== "" ){
                      chatDispatcher.addMessage( messageInput.text );
                      messageInput.text = "";
                      chatModel.updateMessageView();
                  }
              }
          

          And i've tryed to emit dataChanged() signal like that:

          void ChatModel::updateMessageView()
          {
              dataChanged( index( 0 ), index( rowCount() ) );
          }
          
          p3c0P 1 Reply Last reply
          0
          • F FOXLISIN

            @p3c0

            I call it by click on Qml button:

            RoundedButton {
                    id: sendButton;
            
                    text: "send";
            
                    anchors {
                        right: parent.right;
                        bottom: parent.bottom;
                        rightMargin: dp(15);
                        bottomMargin: dp(15);
                    }
            
                    onClicked: sendMessage();
                }
            
                function sendMessage()
                {
                    if( messageInput.text !== "" ){
                        chatDispatcher.addMessage( messageInput.text );
                        messageInput.text = "";
                        chatModel.updateMessageView();
                    }
                }
            

            And i've tryed to emit dataChanged() signal like that:

            void ChatModel::updateMessageView()
            {
                dataChanged( index( 0 ), index( rowCount() ) );
            }
            
            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #5

            @FOXLISIN I dont see where you add new data in the model. What does addMessage do ? The list will show new data only when new data is available in the model.

            157

            F 1 Reply Last reply
            0
            • p3c0P p3c0

              @FOXLISIN I dont see where you add new data in the model. What does addMessage do ? The list will show new data only when new data is available in the model.

              F Offline
              F Offline
              FOXLISIN
              wrote on last edited by
              #6

              @p3c0
              My model gets all data from database through my "Dispatcher" class as i described above.

              See:

              int ChatModel::rowCount( const QModelIndex &theIndex ) const
              {
                  return _ChatDispatcher->messageCount();
              }
              

              And addMessage method inserts data to database. After that i want to redraw my listview

              p3c0P 1 Reply Last reply
              0
              • F FOXLISIN

                @p3c0
                My model gets all data from database through my "Dispatcher" class as i described above.

                See:

                int ChatModel::rowCount( const QModelIndex &theIndex ) const
                {
                    return _ChatDispatcher->messageCount();
                }
                

                And addMessage method inserts data to database. After that i want to redraw my listview

                p3c0P Offline
                p3c0P Offline
                p3c0
                Moderators
                wrote on last edited by
                #7

                @FOXLISIN Did you try checking rowCount() after you added new message ? Does it get updated ?

                157

                1 Reply Last reply
                0
                • F FOXLISIN

                  Hi. During the process of moving from QWidgets to QML I faced with the next problem: changing of C++ model doesn't update QML ListView. But on QWidgets all works as expected, i.e: emitting of dataChanged(index(0), index(rowCount())) signal updates my QListView from QWidgets.

                  My C++ model gets data through "Dispatcher" class, which returns different count of elements and values for roles for different ID, for example:

                  rowCount(...) method of my model looks like this:

                  int ChatModel::rowCount( const QModelIndex &theIndex ) const
                  {
                      return _ChatDispatcher->messageCount();
                  }
                  

                  And here is messageCount() method of my Dispatcher: _DialogID - field of Dispatcher class

                  int ChatDispatcher::messageCount()
                  {
                      return GetMessagesCount( _DialogID );
                  }
                  

                  And when i change _DialogID i want to redraw the ListView by emitting dataChanged(index(0), index(rowCount())) signal. But for QML ListView it doesn't work.

                  I've tryed this instead of dataChanged(..):

                  beginResetModel();
                  endResetModel();
                  

                  It works, but very slowly. Maybe you advise me something useful?

                  A Offline
                  A Offline
                  ahmad98
                  wrote on last edited by
                  #8

                  @FOXLISIN said in Changing of C++ model doesn't update QML ListView:
                  did you solve this problem ?

                  1 Reply Last reply
                  0
                  • IntruderExcluderI Offline
                    IntruderExcluderI Offline
                    IntruderExcluder
                    wrote on last edited by
                    #9

                    The dataChanged signal of models in QML should also say which roles are changed. The 3rd param is missing.

                    1 Reply Last reply
                    0
                    • GrecKoG Offline
                      GrecKoG Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by GrecKo
                      #10

                      When no roles are passed as a parameter, all roles ares assumed to be changed.

                      The most likely error of OP is to not call begin/endInsertRows (or modelReset is all the model is changed)

                      1 Reply Last reply
                      0

                      • Login

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