AbstractItemModel - setData and update TreeView [solved]
I've got a (probably) conceptual question. But first I try to explain the structure of my data and view items.
My data is stored in a DB.
In my code I create a Python (I'm using PyQt) object for each data item that is retrieved from the DB. I evaluate the relations to other objects lazily. The result is a network of objects with several references to each other. Objects can be referenced several times and also recursivly. Therefore I can't use these objects as my input data for an QAbstractItemModel.
I create (following some rules) view objects that represent certain views on my data objects. These view objecs are quite simple. They provide a parent and a children method and a reference to the underlying data object. I have several different views defined, which each consist of a set of view objects. But they partly reference the same underlying data object.
Now I have created some QAbstractItemModels. Some of those models are used to edit data.
And here the question: What is the recommended way to update my data in a way that only those parts of the QTreeViews are rebuild that have changed? I don't want to reset all models after one change, as the state of the QTreeViews would be lost.
What I do so far: I call from the setData() method of my QAbstractItemModel a method that updates the data objects. I don't update any view objects from the QAbstractItemModel. But the method I invoke to update the data objects emits a signal "data_changed" with the changed data object as content. All views are connected to this signal. Now every view checks, wether it is referencing the changed data object in one of its view objects. If not, nothing happens. If the view does reference the data object, the view determines, which view objects needs to be modified. Now the view emits a signal "data_changed". This signal is connected by my QAbstractItemModel implementation. I then invoke a slot which gets the current QPersistentIndexes, determines which are unchanged and updates the QPersistenIndexes. All this between the emitting of LayoutAboutToChange and LayOutChanged. So far so good. I'm totally thrilled by signals and slots. But: Now I'm trouble as it seems that I created an unfortunate circuit. The code crashes and I'm not even surpriced ;-). Starting from within the setData() method I trigger the execution of a slot of the same model, which changes the model. I guess one solution would be to somehow supress the execution of the slot if the slot is in the same model, from which the trigger came. Another could be that I somehow get the trigger of the change out of my setData() method. But how?
A long question ;-). I appreciate any thoughts and ideas and comments.
You should emit the "dataChanged() ":http://doc.qt.nokia.com/4.7/qabstractitemmodel.html#dataChanged signal from your setData() method in the model.
Just to give some feedback of what I have done:
As the changes to my model can vary from just changing data to changing the whole structure, I do a full model reset. To restore the expansion state I track all expands and collapses that happen. I track this "expand-state" with my view objects. When the data has changed I reset the model and re-expand all view objects, that are still the same (unchanged by the changes in the underlying data objects).
I've rewritten parts of my model and it works fine. I just don't call any upates like dataChanged() from setData() anymore and leave all the updating to the full model reset.