PDA

View Full Version : How to tell a QAbstractItemModel that data has been inserted or removed? (4.8)



JasonC
5th March 2015, 07:16
If something causes say, a row to be inserted in the underlying data structure behind a QAbstractItemModel, what do I do? How do I let the QAbstractItemModel know that data was inserted so that views connected to it can be notified and updated?

At first I thought I should have the underlying data structure somehow trigger its attached QAbstractItemModel to emit rowsAboutToBeInserted just before the underlying data is modified, and rowsInserted afterwards. Except, the documentation for these two signals contains the following note:

> It can only be emitted by the QAbstractItemModel implementation, and cannot be explicitly emitted in subclass code.

Ok, so that means my own item models aren't allowed to signal that rows were inserted? I don't understand how this is useful, then...

Then there is also insertRows, which I can't understand the purpose of. This doesn't seem to be what I want. This seems to be a way to insert (blank, I guess?) rows in the underlying data via the model interface, which isn't what I'm trying to do (nor can I conceive of any situation in which this would be done).

I have data stored in a class. The data changes and an element is inserted. So how do I ultimately cause the attached view to reflect the change, since I'm not allowed to call rowsInserted()?

faldzip
5th March 2015, 08:28
You probably missed the "see also" section in rowsAboutToBeInserted() as there is beginInsertRows() method mentioned and that's the one you should use. AFAIK there should be an example on inserting rows in the docs with some nice images showing how indices change.

JasonC
5th March 2015, 09:13
Thanks. I did see that but was still uncertain: The documentation is worded in a way that makes it appear that beginInsertRow/endInsertRow should be called when the *model* is causing the row insertion (i.e. they're called from a subclass's insertRow implementation, which I don't have and don't need to have), rather than in response to the data changing "on its own" (i.e. not via the model's insertRow). That's not my situation, though. Is that the case or did I misinterpret?

The other thing that confused me about those is: Does that mean I need to add the ability to my underlying data class to emit signals or otherwise notify the list model *before* data is changed as well as after, so that I can call beginInsertRow and endInsertRow before and after the data changes? Or can I just call begin+end together after the data changes... ? This seems weird to me because it means that whatever class is holding the data has to have the ability to announce changes before they happen, and philosophically I don't like adding functionality like that as it is *only* used for UI in this case and I don't want UI-specific functionality in my data classes (I don't mind, I just don't want to unless I'm sure it's the best option).

I couldn't and still can't find the example you're referring to.

anda_skoa
5th March 2015, 10:59
Thanks. I did see that but was still uncertain: The documentation is worded in a way that makes it appear that beginInsertRow/endInsertRow should be called when the *model* is causing the row insertion

Whenever rows are inserted, independend on whether they are insterted through the model's API, e.g. by a view, or by the model itself.



The other thing that confused me about those is: Does that mean I need to add the ability to my underlying data class to emit signals or otherwise notify the list model *before* data is changed as well as after, so that I can call beginInsertRow and endInsertRow before and after the data changes? Or can I just call begin+end together after the data changes... ?
I think you can do that.

Usually, when I am dealing with an uncooperative data source, I'll try to make the model still behave like it would with a cooperative data base by making sure rowCount() and data() work with the old row indexes until after beginInsertRows() returns.

But I think the standard views only use the about signal to avoid updating until the end of the change.

Cheers,
_

JasonC
5th March 2015, 19:38
Perfect, thanks a lot for your time.

J