Search code examples
c++multithreadingqtqlistview

Updating QListView from aggregation thread makes the GUI freeze


In a simple application, I have a Mainwindow containing a QListView using a QAbstractListModel.

When I start the application I start a single thread using a thread worker that gets data records from an external web service, it gets 10-20 records each Iteration.

Problem:

In the HttpAggrigator class that started from the thread worker in the big while loop that iterates on each returned record, I emit a signal to another class called ViewControler, and its job is to populate the QListView model.

In this part, my window just freezes until all the items are set in the listview.

I checked with the profiling tool called “Sleepy” and indeed, the ViewControler method that sets the items is causing the slow down.

The flow:

  • MainWindow -> starts HttpAggrigator (in a different thread ).
  • HttpAggrigator -> gets records -> starts to iterate them ( to fill data objects ).
  • HttpAggrigator -> emits a signal to ViewControler on each record iteration to build item into MainWindow QListView.

How can I prevent the GUI freeze and slow down when adding items?


Solution

  • Everytime you're adding item to model you cause view to repaint itself. You should agregate items into one list and insert it into model at once. You will have 1 repaint instead of n repaints

    Use method like this with more than one item at a time

    void LostModel::addItems(QList<MyItem *> items)
    {
        if(items.size())
        {
            int begin = MyItemList.size();
    
            beginInsertRows(QModelIndex(), begin, begin + items.size() - 1);
            MyItemList.append(items);
            endInsertRows();
        }
    }