Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Best Approach for minimal footprint QListView of many thumbnail images
QtWS25 Last Chance

Best Approach for minimal footprint QListView of many thumbnail images

Scheduled Pinned Locked Moved General and Desktop
11 Posts 4 Posters 4.9k 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.
  • JMO_GSJ Offline
    JMO_GSJ Offline
    JMO_GS
    wrote on last edited by
    #1

    I've got a QListView (using QStandardItemModel) monitoring a large directory tree and showing a large number of thumbnails recursively stored within it. The problem I have is that there are so many thumbnails that it is beginning to impact performance of our application. I would very much like to have the thumbnails only load the actual images when they absolutely must be shown - that is to say, only when the user scrolls to bring the items into the view.

    Right now the code is just scanning and create a QStandardItem with icon for each image right at the start. Terribly wasteful.

    I'm looking for a general approach on how to this. I want to make a "virtual" list-View, so to speak.

    So far, the only thing I can come up with is a custom QStandardItem-derivative which stores a thumbnail path. It defers loading the image until its override of QStandardItem::data() is called with Qt::DecorationRole. The idea is that Qt won't call this until it needs to actually display the icon.

    Does this sound like a good approach? Is there a better one I should be using? Perhaps a different view/model/item class? And what about the UNloading of thumbnails when items are scrolled out of view?

    I'm not looking for someone to write my code for me, just to be pointed in the right direction with a bit of explanation. Or in the very least perhaps the recommendation of what approaches NOT to try.

    As you can probably tell my Qt Model/View experience is thin and I would hate to waste cycles going down the wrong road.

    thanks,

    -Joe

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      I think you can get this using a custom model
      Where you override ( as the keys ones)
      bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
      void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE;

      http://doc.qt.io/qt-5/qtwidgets-itemviews-fetchmore-example.html

      Note: The sample is based on QAbstractListModel. You might want QAbstractItemModel.

      JMO_GSJ 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        One thing you can do is use a "rolling window" in your model that loads only the thumbnails from the visible items. You could also delay the loading of the thumbnails until e.g. the view stopped scrolling for a certain amount of time showing a place holder in between.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          Hi! Another possibility would be using a custom delegate to render the items. The model would only know the names of the files and the delegates would create the thumbnails automatically once they are shown. Also, once the delegates get automatically destroyed, the thumbnails would get destroyed, too. I think this would result in minimal memory footprint, although the GUI might feel laggy. If the latter should prove to be unacceptable you could use one or more seperate threads for the computation of the thumbnails.

          JMO_GSJ 2 Replies Last reply
          3
          • mrjjM mrjj

            Hi
            I think you can get this using a custom model
            Where you override ( as the keys ones)
            bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
            void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE;

            http://doc.qt.io/qt-5/qtwidgets-itemviews-fetchmore-example.html

            Note: The sample is based on QAbstractListModel. You might want QAbstractItemModel.

            JMO_GSJ Offline
            JMO_GSJ Offline
            JMO_GS
            wrote on last edited by
            #5

            @mrjj Thanks, I'm looking at that example now. Seems to be a bit more involved when QAbstractItemModel is involved vs QAbstractListModel but I should be able to figure something out.

            mrjjM 1 Reply Last reply
            0
            • ? A Former User

              Hi! Another possibility would be using a custom delegate to render the items. The model would only know the names of the files and the delegates would create the thumbnails automatically once they are shown. Also, once the delegates get automatically destroyed, the thumbnails would get destroyed, too. I think this would result in minimal memory footprint, although the GUI might feel laggy. If the latter should prove to be unacceptable you could use one or more seperate threads for the computation of the thumbnails.

              JMO_GSJ Offline
              JMO_GSJ Offline
              JMO_GS
              wrote on last edited by
              #6

              @Wieland That sounds like exactly what I need. I guess I have a lot of reading to do...

              1 Reply Last reply
              0
              • JMO_GSJ JMO_GS

                @mrjj Thanks, I'm looking at that example now. Seems to be a bit more involved when QAbstractItemModel is involved vs QAbstractListModel but I should be able to figure something out.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @JMO_GS
                Hi
                The rolling window as @SGaist might be better than the FetchMore way, as fetch cannot unload again. ( as far as I know )
                Or using delegate as @Wieland suggests.

                Not sure would be the easiest to get doing.

                Also I kinda like your logic using QStandardItem::data() and Qt::DecorationRole but im not sure
                when it would be called.

                If you need to "unload" over time, you should aim for solution that does this easy.

                JMO_GSJ 1 Reply Last reply
                0
                • mrjjM mrjj

                  @JMO_GS
                  Hi
                  The rolling window as @SGaist might be better than the FetchMore way, as fetch cannot unload again. ( as far as I know )
                  Or using delegate as @Wieland suggests.

                  Not sure would be the easiest to get doing.

                  Also I kinda like your logic using QStandardItem::data() and Qt::DecorationRole but im not sure
                  when it would be called.

                  If you need to "unload" over time, you should aim for solution that does this easy.

                  JMO_GSJ Offline
                  JMO_GSJ Offline
                  JMO_GS
                  wrote on last edited by
                  #8

                  @mrjj I'm not sure what you or @SGaist are talking about by a "rolling window". Obviously that describes the effect I am trying to accomplish: A rolling window... class that loads/unloads thumbnails as needed. But I'm sure if you literally mean some specific Qt class or not? Whatever I use to achieve this must somehow be tied into the existing QListView signals, yes? Like checking scrolling notifications or the like?

                  mrjjM 1 Reply Last reply
                  0
                  • JMO_GSJ JMO_GS

                    @mrjj I'm not sure what you or @SGaist are talking about by a "rolling window". Obviously that describes the effect I am trying to accomplish: A rolling window... class that loads/unloads thumbnails as needed. But I'm sure if you literally mean some specific Qt class or not? Whatever I use to achieve this must somehow be tied into the existing QListView signals, yes? Like checking scrolling notifications or the like?

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @JMO_GS
                    Hi
                    Sorry for being vague.
                    There is not class for it as such. It would be subclassing the view to be able to catch the events
                    related to scrolling. For each such event, look if the items actually visible and handle when new ones comes
                    into view and when some leaves the view ( for unloading)

                    I think I would start with the Delegate and see if laggy as it would give u "unloading" automatically.

                    1 Reply Last reply
                    0
                    • ? A Former User

                      Hi! Another possibility would be using a custom delegate to render the items. The model would only know the names of the files and the delegates would create the thumbnails automatically once they are shown. Also, once the delegates get automatically destroyed, the thumbnails would get destroyed, too. I think this would result in minimal memory footprint, although the GUI might feel laggy. If the latter should prove to be unacceptable you could use one or more seperate threads for the computation of the thumbnails.

                      JMO_GSJ Offline
                      JMO_GSJ Offline
                      JMO_GS
                      wrote on last edited by
                      #10

                      @Wieland The custom delegate proved to be the best approach for me, thanks.

                      • I just created a class derived from QStyledItemDelegate and installed it to the QStandardItemModel I was already using.
                      • I overrode it initStyleOption() function. which called the base class version there (which found no icon)
                      • Then in my derived version, detected this lack of icon and issued an asynchronous request to load it.
                      • In the meantime, I filled out the QStyleOptionViewItem with a default empty icon and returned this to the caller. So for a brief moment, the user sees an blank square
                      • When the asynchronous request to load the icon is done, it signals my widget which updates the items icon.
                        *To make things simpler, I made sure that when I create all of my QStandardModelItems, I give them a custom piece of data (a custom role) that holds the path of the thumbnail to be loaded.
                        *I have a timer running that periodically checks and unloads non-visible icons. This timer gets reset every time the user scrolls or loads a new icon.

                      Works quite well. Thanks

                      mrjjM 1 Reply Last reply
                      2
                      • JMO_GSJ JMO_GS

                        @Wieland The custom delegate proved to be the best approach for me, thanks.

                        • I just created a class derived from QStyledItemDelegate and installed it to the QStandardItemModel I was already using.
                        • I overrode it initStyleOption() function. which called the base class version there (which found no icon)
                        • Then in my derived version, detected this lack of icon and issued an asynchronous request to load it.
                        • In the meantime, I filled out the QStyleOptionViewItem with a default empty icon and returned this to the caller. So for a brief moment, the user sees an blank square
                        • When the asynchronous request to load the icon is done, it signals my widget which updates the items icon.
                          *To make things simpler, I made sure that when I create all of my QStandardModelItems, I give them a custom piece of data (a custom role) that holds the path of the thumbnail to be loaded.
                          *I have a timer running that periodically checks and unloads non-visible icons. This timer gets reset every time the user scrolls or loads a new icon.

                        Works quite well. Thanks

                        mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @JMO_GS
                        Thank you for reporting back. Its very helpful for others forum users. :)

                        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