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. Lazy Loading File Icons to QTableWidget?
Forum Updated to NodeBB v4.3 + New Features

Lazy Loading File Icons to QTableWidget?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 789 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.
  • S Offline
    S Offline
    ScottLupton
    wrote on 14 May 2018, 13:23 last edited by ScottLupton
    #1

    I'm displaying the contents of a directory in a QTableWidget along with the file icons. I've found that it can take a long time to load the icons, particularly with icons that are embedded in executable files. To make the application more responsive I changed it to show the directory contents immediately and then tried to load the icons gradually from a worker thread. However, I'm not sure how to implement the icon loading in the worker thread.

    I tried creating an IconLoader class to load the icons from a QFileIconProvider in a worker thread:

    struct IconRequest
    {
        QFileInfo fileInfo;
        int row;
        QIcon icon;
    };
    
    class IconLoader : public QObject
    {
        Q_OBJECT
    private:
        QFileIconProvider m_IconProvider;
    signals:
        void IconReady(IconRequest* request);  
    private slots:
        void LoadIconReq(IconRequest* request);
        {
            request->icon = m_IconProvider.icon(request->fileInfo);
            emit IconReady(request);
        }
    };
    

    I created connections for requesting and receiving icons and moved the IconLoader to a QThread:

    m_IconLoader = new IconLoader;
    m_IconLoader->moveToThread(&m_IconLoaderThread);
    connect(this, SIGNAL(RequestingIcon(IconRequest*)), m_IconLoader, SLOT(LoadIconReq(IconRequest*)));
    connect(m_IconLoader, SIGNAL(IconReady(IconRequest*)), this, SLOT(SetIcon(IconRequest*)));
    connect(&m_IconLoaderThread, SIGNAL(finished()), m_IconLoader, SLOT(deleteLater()));
    m_IconLoaderThread.start();
    

    After the IconReady() signal is emitted by the worker thread the SetIcon() slot is called in the main thread (m_dirListing is a pointer to a QTableWidget):

    void FileList::SetIcon(IconRequest* request)
    {
        m_dirListing->item(request->row, 0)->setIcon(request->icon);
        delete request;
    }
    

    Unfortunately, the directory contents still do not display until all the icons have loaded. Investigating the problem it appears that QFileIconProvider::icon() is actually a very fast operation that returns immediately. The time consuming operation seems to be QTableWidgetItem::setIcon() which appears to be where the icon is actually loaded. As QTableWidgetItem::setIcon() is called from the main thread the program still becomes unresponsive when loading directories.

    Since the above approach doesn't work I'm unsure how to get lazy loading of icons to work. QTableWidgetItem::setIcon() couldn't be called from the worker thread since QTableWidgetItem is reenterant and not thread-safe.

    How can I load the icon in the worker thread so it can be quickly set in the main thread?

    1 Reply Last reply
    0
    • C Online
      C Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 14 May 2018, 16:54 last edited by
      #2

      Use an own model and set the data there. QTableWidget is just a convenience class which was designed for simple stuff (just like QTreeWidget).

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      2
      • S Offline
        S Offline
        ScottLupton
        wrote on 14 May 2018, 17:26 last edited by
        #3

        That probably would have been best, but at this point it would require a lot of changes.

        The application is complete and generally works well, but I later found that opening directories containing a lot of executables with embedded icons could be very slow. I was hoping to find a way of addressing that without making major changes.

        1 Reply Last reply
        0

        1/3

        14 May 2018, 13:23

        • Login

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