PDA

View Full Version : calling QCoreApplication::processEvents(); wenn filling a model with data



gig-raf
24th March 2015, 15:12
Hi All,

I am filling a QStandardItemModel with data, in fact 5000 row with 8 columns. At the same time as the model is being filled I am playing a mp3 file via the QMultimedia player and updating a QSlider with the duration.

If I call the function below my main gui thread freezes up and becomes unrepsonsive.



void MainWindow::addModl(QList<QStandardItem*> &data)
{
plmodel->appendRow(data);
}


by calling the processEvents() the problem of the freezing main thread is solved but I have noticed that the QSlider is not updated every 1 seconds, but from to time the update happends with 2-3 seconds delay.





void MainWindow::addModl(QList<QStandardItem*> &data)
{
QCoreApplication::processEvents();
plmodel->appendRow(data);
}





So my question is, is calling the processEvents() the correct approach to prevent the main gui from freezing up?
-and are the gaps I see in the QSLider to be expected.

In my case it is not vital that QSlider is updated every second, but I am thinking there could be other scenarios were you need all widgets to be updated in ms, in that case filling the model the way I am doing is not fine.


What do you guys do when you have to do some heavy operation like this?

anda_skoa
24th March 2015, 16:11
Do you have only transient access to the data or is the data also available later on?

I.e. do you have to copy it into a standard item model before it is gone or does the application have access to the data at all times?

In the second case it is likely a lot better to just create a model that interfaces with the actual data, instead of duplicating the data.

Cheers,
_

gig-raf
24th March 2015, 17:28
In fact I am reading TAGs from mp3 files storing them in a DB (if not already stored), and then populating the model with the data from the DB.

The problem is that when populating the model the other widgets are not updated as fast as I would like them too. At least not when I use the code I posted below.


Could I write a model the interfaces the actual data in this case? I think not.

thanks for your time!

cheers,

anda_skoa
25th March 2015, 08:49
Any reason you can't use any of the database models?

Cheers,
_

gig-raf
25th March 2015, 21:52
I could use a database model in this case. Would populating such a model be any different in terms of main thread blocking?

I will give it a go, and let you know if those models are any better.

Thanks again....

anda_skoa
26th March 2015, 08:14
Well, I am only guessing, but your current setup sounds like you are adding one row after another, most likely while the model is already shown in a view.
Each add results in updates on the view, causes memory to be copied, items to be created, etc.

A model that just interfaces with the data would just report the total number of rows to the view. The view would then get all data it currently needs.
No need for copying large amounts of data or even accessing data currently not displayed.

Cheers,
_

gig-raf
26th March 2015, 15:57
You are correct in your assumption. I do add the rows one by one, and the view is updated the whole time.

but in this case I guess I wouldn't be able to do it any other way?. I am talking about a user adding 5000 or more titles to a play list. The model doesnt know yet what files the user will add so the data will have to be copied. - at least the first time they are added. the next time it could be retrieved from a database.

How does other tools such as Itunes, banshee etc. deal with this kind of problem. I believe they will retrieve the data from the files, but not update the view until all rows are retrieved.

anda_skoa
26th March 2015, 17:43
Even if the user adds files one by one (not likely), in the case of a model that is merely an interface to the data, it doesn't have to copy the data that is currently not needed by the view.

In the more likely case that a users selects lists of files, e.g. whole directories or even directory trees, a model can expose all new rows in one go, or in chunks, etc.

Cheers,
_

gig-raf
26th March 2015, 20:36
In the more likely case that a users selects lists of files, e.g. whole directories or even directory trees, a model can expose all new rows in one go, or in chunks, etc.

I might have a wrong idea here. Please be patient with me :-)

so you idea is to just add chunks of let say 100 rows at the time?

is there away to do that? wont I still have to add the rows one by one to the model?

-Remember it is likely the model has data already, I dont want to loose this data.

anda_skoa
27th March 2015, 08:21
Exposing more rows in chunks is one option, e.g. if doing all the data in one go would leave the UI empty for too long.

A model can expose any number of rows anywhere in its range at any time, see QAbstractItemModel::beginInsertRows().

Cheers,
_