PDA

View Full Version : GUI becomes unresponsive when adding more items to TreeModel



chithara
16th May 2019, 03:44
Hi,

I have a QTreeView with custom Read-only TreeModel derived from QAbstractItemModel. On click of a TreeItem, I have to call the backend layer to get the data and add the response to the parent TreeItem.

Data coming from backend is divided into chunks(say 100 objects at a time which is pushed to the model, then 100 objects pushed to the model, so on). View is getting updated as and when model is getting updated by using BeginInsertRows()/EndInsertRows().

My problem here is, When there are 10k data items coming in response which keeps on adding to model in chunks , the Treeview becomes unresponsive till the entire data gets added. I am not able to use scrollbar, click on any other TreeItem. Is there any way in Qt to make the data addition to the model/view without affecting other GUI controls?

anda_skoa
17th May 2019, 14:40
Adding chunks sounds already like a good way to avoid blocking, but maybe you are using a blocking loop until you have all chunks?

Cheers,
_

chithara
20th May 2019, 05:17
The calls are in Asynchronous way. The backend layer push the data to the GUI layer and the GUI emits it every time to the respective widget. How the emit call works in Qt if it has queue of data to be pushed ? Is it blocking ?

anda_skoa
20th May 2019, 08:33
A single pair of beginInsertRows() and endInsertRows() with 100 rows should not be taking long.

Have you measured the time for this?
E.g. using QElapsedTimer.

Something like


QElapsedTimer timer;
timer.start();

beginInserRows(....);

// update your data

endInsertRows();

qDebug() << "Update time for one chunk of data:" << timer.elapsed();


This is the time the UI will be "blocked" as this happens on the main thread the same way as processing user and paint events.

Be sure that the method doing this is really being called asynchronously, i.e. execution returning to the event loop between calls.

Cheers,
_

chithara
21st May 2019, 07:35
Hi, a correction on the understanding. Its not 100 rows insertion at a time to the model.
A single pair of beginInsertRows() and endInsertRows() with 1 row at a time. The entire insertion is happening in a loop of count 100.
Is that the problem ?

Lesiok
21st May 2019, 08:19
Of course.
beginInsertRows();
Loop....
endInsertRows();

d_stranz
21st May 2019, 16:04
Is that the problem ?

As Lesiok said, yes, of course. What you are doing is forcing the UI to update with -every- new row. Do as he suggests - call beginInsertRows() with a row count of 100, add the rows to your internal model, then call endInsertRows() to update the UI.

chithara
22nd May 2019, 10:13
What will be the first and last index do I need to give in beginInsertRows() ,If I am trying to append 100 nodes to parent.

Currently my code is

beginInsertRows(parent, 0, 0);
for ()
{
parentNode->AppendChild(child));
}

endInsertRows();

d_stranz
22nd May 2019, 16:45
If I am trying to append 100 nodes to parent.

Your code is incorrect. Read the documentation. QAbstractItemModel::beginInsertRows() explains it.