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. Loading QAbstractListModel takes too long
Qt 6.11 is out! See what's new in the release blog

Loading QAbstractListModel takes too long

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 5 Posters 2.4k 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.
  • A Offline
    A Offline
    Adso4
    wrote on last edited by
    #1

    I have a QML view that loads a ListView with a lot of components. Each Item in the view has several rectangles, texts, and other ListView's as children.

    The data comes from a model that inherits from QAbstractListModel. I have a refresh() methods that does:

    • beginResetModel()
    • //update all model data
    • endResetModel()

    This works fine, but the problem is that depending on the number of items I have, it can take too long to load the view.

    Would it be possible to load model data partially? Or how can I display the view with just a few items loaded while the rest (the ones that are not still visible) are loading?

    Since the view has a scrollbar, it would be great to load just the visible items first.

    J.HilkJ 1 Reply Last reply
    0
    • A Adso4

      I have a QML view that loads a ListView with a lot of components. Each Item in the view has several rectangles, texts, and other ListView's as children.

      The data comes from a model that inherits from QAbstractListModel. I have a refresh() methods that does:

      • beginResetModel()
      • //update all model data
      • endResetModel()

      This works fine, but the problem is that depending on the number of items I have, it can take too long to load the view.

      Would it be possible to load model data partially? Or how can I display the view with just a few items loaded while the rest (the ones that are not still visible) are loading?

      Since the view has a scrollbar, it would be great to load just the visible items first.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Adso4 IIRC ListVIew should do that already in advance (Loading only what you see), but just in case:

      Move your delegate in its own QML file, make a loader your delegate, set it to active, if the current index is equal to the index +- N(depending on how many you want to show at once


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      GrecKoG 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        @Adso4 IIRC ListVIew should do that already in advance (Loading only what you see), but just in case:

        Move your delegate in its own QML file, make a loader your delegate, set it to active, if the current index is equal to the index +- N(depending on how many you want to show at once

        GrecKoG Offline
        GrecKoG Offline
        GrecKo
        Qt Champions 2018
        wrote on last edited by
        #3

        @J-Hilk said in Loading QAbstractListModel takes too long:

        @Adso4 IIRC ListVIew should do that already in advance (Loading only what you see), but just in case:

        Move your delegate in its own QML file, make a loader your delegate, set it to active, if the current index is equal to the index +- N(depending on how many you want to show at once

        Better yet, don't try a sketchy workaround and figure out if the ListView behaves as it should (make sure not all delegates are created by monitoring listView.contentItem.chlildren.length), and if not, determine why.

        How do you set the dimension of your ListView?
        anchors.fill: parent, using a layout, height: count * delegateHeight, ...?

        1 Reply Last reply
        1
        • A Offline
          A Offline
          Adso4
          wrote on last edited by
          #4

          The listView in placed inside an item and it gets its parent size. The model comes from an implementation of QAbstractListModel and the delegate is a separate QML component.

          Probably I didn't explain myself properly. The problem is not in the model refresh (which updates the data between begin and end resteModel). This is done quite fast. The issues come when drawing the list. Is there when it needs several seconds to be displayed. But once the listView is displayed, it behaves correctly.

          GrecKoG 1 Reply Last reply
          0
          • A Adso4

            The listView in placed inside an item and it gets its parent size. The model comes from an implementation of QAbstractListModel and the delegate is a separate QML component.

            Probably I didn't explain myself properly. The problem is not in the model refresh (which updates the data between begin and end resteModel). This is done quite fast. The issues come when drawing the list. Is there when it needs several seconds to be displayed. But once the listView is displayed, it behaves correctly.

            GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            @Adso4 said in Loading QAbstractListModel takes too long:

            Probably I didn't explain myself properly. The problem is not in the model refresh (which updates the data between begin and end resteModel). This is done quite fast. The issues come when drawing the list. Is there when it needs several seconds to be displayed. But once the listView is displayed, it behaves correctly.

            I understood that correctly, I believe it's because your ListView instantiates too much delegates.

            As always, try to provide a minimal reproducible example of your problem. We can't help much more without it, and it'll also help you better figure out the issue.

            Have you checked the number of delegates created like I mentioned ?

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sonicss
              wrote on last edited by sonicss
              #6

              In my case ( the software run on ARM A7 454MHz MCU),The Listview refresh data take about 1s.

              beginResetModel() and endResetModel() will load all of the data and reset the listvew. It take more time. so I use like below:

                  QModelIndex topLeft = createIndex(0, 0);
                  QModelIndex bottomRight = createIndex(rows, 1);
                  emit dataChanged(topLeft, bottomRight);
              

              emit dataChanged signal can refresh what's the datas u want.

              1 Reply Last reply
              1
              • B Offline
                B Offline
                Bob64
                wrote on last edited by
                #7

                As mentioned in previous post, the root of the issue is likely to be that you are resetting the entire model. As mentioned, if data in an existing element changes, then emit dataChanged but also look at begin/endInsertRows and begin/endRemoveRows to notify of structural changes to your data. Rule of thumb is always to update incrementally wherever possible and avoid full resets except for the probably limited cases where you are genuinely reinitialising your model.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Adso4
                  wrote on last edited by Adso4
                  #8

                  In my case, I just need to reset the entire model. Once it is loaded, there won't be any insert or update. I need to speed up the model refresh. This is my pseudo-code:

                  **MainModel.cpp**
                  
                  MainModel::refresh() {
                      listViewModel_1->refresh()
                      emit changed();
                  }
                  
                  **ListViewModel_1.cpp (inherits from QAbstractListModel)**
                  
                  ListViewModel_1::refresh() {
                      beginResetModel();
                      newItems = updateNewItems(); // add items to ListViewModel_2. Each item on m_items has a ListViewModel_2 object (childs)
                      m_items.clear();
                      for (item in newItems) {
                          m_items.push_back(item)
                      }
                      endResetModel();
                  }
                  
                  **ListViewModel_2.cpp (inherits from QAbstractListModel)**
                  
                  ListViewModel_2::addNewItem(newItem) {
                      beginInsertRows(QModelIndex(), rowCount(), rowCount());
                      m_childs.push_back(model);
                      endInsertRows();
                  }
                  

                  Should I use begin/endInserRow instead of begin/EndResetModel()? Any other suggestion?

                  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