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. Optimizations / Substituions for QListWidget?
Forum Updated to NodeBB v4.3 + New Features

Optimizations / Substituions for QListWidget?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qlistwidget
7 Posts 4 Posters 2.6k 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.
  • SolaVitaeS Offline
    SolaVitaeS Offline
    SolaVitae
    wrote on last edited by
    #1

    Is there any way to optimize the setting of a ListWidgetItem's widget in a QListWidget?, currently when i have a list of ~ 200 items, setting the item's widgets causes my app to freeze whilst it is doing that for ~ 15 seconds, The only thing the widget that im setting it to contains is three QLabels, one for a text field, and one for an image, and one for a color block. Even when i dont initialize the widget's ui, and simply set it to an empty widget it still takes a high amount of time.

    I don't believe i can thread it as it involves UI elements, so i'm not sure if im doing something wrong, or if QListWidget isnt the data view i should be using in this situation?

    I didn't post any code because its litteraly just making a new QListWidgetItem, adding it to the list, then setting its widget to a custom widget with a UI, in a loop for a search result, which can range from 3-500 results

    J.HilkJ 1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      You must be doing something wrong - adding 200 items will not take 15s. Please show us your code.

      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
      0
      • SolaVitaeS SolaVitae

        Is there any way to optimize the setting of a ListWidgetItem's widget in a QListWidget?, currently when i have a list of ~ 200 items, setting the item's widgets causes my app to freeze whilst it is doing that for ~ 15 seconds, The only thing the widget that im setting it to contains is three QLabels, one for a text field, and one for an image, and one for a color block. Even when i dont initialize the widget's ui, and simply set it to an empty widget it still takes a high amount of time.

        I don't believe i can thread it as it involves UI elements, so i'm not sure if im doing something wrong, or if QListWidget isnt the data view i should be using in this situation?

        I didn't post any code because its litteraly just making a new QListWidgetItem, adding it to the list, then setting its widget to a custom widget with a UI, in a loop for a search result, which can range from 3-500 results

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

        @SolaVitae said in Optimizations / Substituions for QListWidget?:

        Labels, one for a text field, and one for an image

        hi,
        please show us, how you create the custom ListWidgetItems.

        If you for example create a new QImage /QPixmap for each of your 200 entries, that can take a really long time to do, depending on how you do it.


        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.

        1 Reply Last reply
        0
        • SolaVitaeS Offline
          SolaVitaeS Offline
          SolaVitae
          wrote on last edited by SolaVitae
          #4

          They are created like so:

          while (q.next()) {
          
          		QString iconUrl = q.value(5).toString();
          		QString fileName;
          		ItemSearchItem *isi = new ItemSearchItem();
          		QListWidgetItem *lwi = new QListWidgetItem();
          		lwi->setSizeHint(QSize(210, 30));
          		fileName = ac()->dataPath + "\\cache\\icons\\" + q.value(1).toString() + ".png";
          		if (!fileExists(fileName)) {
          			//downloadList.insert(iconUrl, isi->uid);
          		}
          		resultList->addItem(lwi);
          		resultList->setItemWidget(lwi, isi);
          		uidIndex.insert(q.value(1).toString(), isi);
          	}
          

          Q is a QSqlQuery, the constructor/definition for ItemSearchItem is:

          class ItemSearchItem : public QWidget {
          	Q_OBJECT
          public:
          	explicit ItemSearchItem(QWidget *parent = 0);
          
          	Ui::ItemSearchItem *ui;
          
          	QString itemName;
          	QString iconPath;
          	QLabel *itemIconLabel;
          	QLabel *itemNameLabel;
          
          	QString link;
          	QString uid;
          
          };
          
          ItemSearchItem::ItemSearchItem(QWidget *parent) :
          	QWidget(parent)
          {
          	itemNameLabel = findChild<QLabel*>("itemName");
          	itemIconLabel = findChild<QLabel*>("itemIcon");
          
          

          the Constructor typically has a UI setup line in it, but i removed it for testing, and commenting out the setItemWidget line results in it finishing in less than 1 second

          J.HilkJ 1 Reply Last reply
          0
          • SolaVitaeS SolaVitae

            They are created like so:

            while (q.next()) {
            
            		QString iconUrl = q.value(5).toString();
            		QString fileName;
            		ItemSearchItem *isi = new ItemSearchItem();
            		QListWidgetItem *lwi = new QListWidgetItem();
            		lwi->setSizeHint(QSize(210, 30));
            		fileName = ac()->dataPath + "\\cache\\icons\\" + q.value(1).toString() + ".png";
            		if (!fileExists(fileName)) {
            			//downloadList.insert(iconUrl, isi->uid);
            		}
            		resultList->addItem(lwi);
            		resultList->setItemWidget(lwi, isi);
            		uidIndex.insert(q.value(1).toString(), isi);
            	}
            

            Q is a QSqlQuery, the constructor/definition for ItemSearchItem is:

            class ItemSearchItem : public QWidget {
            	Q_OBJECT
            public:
            	explicit ItemSearchItem(QWidget *parent = 0);
            
            	Ui::ItemSearchItem *ui;
            
            	QString itemName;
            	QString iconPath;
            	QLabel *itemIconLabel;
            	QLabel *itemNameLabel;
            
            	QString link;
            	QString uid;
            
            };
            
            ItemSearchItem::ItemSearchItem(QWidget *parent) :
            	QWidget(parent)
            {
            	itemNameLabel = findChild<QLabel*>("itemName");
            	itemIconLabel = findChild<QLabel*>("itemIcon");
            
            

            the Constructor typically has a UI setup line in it, but i removed it for testing, and commenting out the setItemWidget line results in it finishing in less than 1 second

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

            @SolaVitae said in Optimizations / Substituions for QListWidget?:

            the Constructor typically has a UI setup line in it, but i removed it for testing, and commenting out the setItemWidget line results in it finishing in less than 1 second

            Yeah I believe that to be the issue.

            You create a new QImage/QPixmap in your UI-file each time you call new. That will take time, parsing the file in your ressources, consturcting an Qimage then displaying it.

            Much cheaper should be if you modify your constructor, so that it expects an QImage, Than you create the Qimage before your Query and simply pass it as a copy, much cheaper than new construction.

            Should increase the speed significantly.


            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.

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

              @SolaVitae said in Optimizations / Substituions for QListWidget?:

              the Constructor typically has a UI setup line in it, but i removed it for testing, and commenting out the setItemWidget line results in it finishing in less than 1 second

              Yeah I believe that to be the issue.

              You create a new QImage/QPixmap in your UI-file each time you call new. That will take time, parsing the file in your ressources, consturcting an Qimage then displaying it.

              Much cheaper should be if you modify your constructor, so that it expects an QImage, Than you create the Qimage before your Query and simply pass it as a copy, much cheaper than new construction.

              Should increase the speed significantly.

              SolaVitaeS Offline
              SolaVitaeS Offline
              SolaVitae
              wrote on last edited by
              #6

              @J.Hilk
              I thought that might have some effect on it, but even when I remove every line from the constructor, and remove all references to the ui, even removing the include for it, and it still takes abnormal amounts of time, Even when i circumvent the entire ItemSearchItem, and just try to set it to a regular empty QWidget it still takes awhile.

              But, after just adding empty widgets to items after, to test the speed comparison of adding custom widgets, versus adding empty stock QWidgets, i noticed it took about twice as long, which lead me to my solution. I don't know why exactly, but adding a list item, then setting its widget in a loop seems to take an increasing amount of time based on how many items you've added, after each item it would take more and more time to set the widget of the next item. So from that i just made two loops instead of one, one to add all the items, and then one after to set all the item widgets, and now it takes less than 1 second to complete both operations.

              1 Reply Last reply
              1
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #7

                setItemWidget should come with a huge warning about it being the wrong solution in 90% of the cases.

                What you need is a QStyledItemDelegate.
                use QListWidgetItem::setData to store your text, image and color in 3 different roles (Qt::EditRole, Qt::DecorationRole and Qt::UserRole appear to be the most natural choices)

                then subclass QStyledItemDelegate and reimplement paint (you can find Qt's implementation here to use as a starting point)

                finally just call QListWidget::setItemDelegate to assign the delegate to the view

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                4

                • Login

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