[pygtk] gtk.GenericTreeModel, tricky one...

Markus W. Barth markus at sismografo.es
Mon Jun 2 19:04:12 WST 2008


I am working on a package that provides some models for use with SQLObject 
(see http://www.sqlobject.org for further details), thus creating database 
frontends is made a lot easier.

Internally, the model uses a python list of SQLObject instances.

Now I have bumped into the following:

As long as I use _one_ instance of the model (SqlListView), there are no 
problems, but as soon as I use two instances of the model, strange behaviour 
starts to happen, apart from getting the following assertion error.

(main.py:16261): CRITICAL **: pygtk_generic_tree_model_get_value: assertion 
`VALID_ITER(iter, tree_model)' failed
(yes, self.row_deleted() is called for every row that is deleted)

But things don't stop here. The module contains two classes of models:

* SqlListModel
* SlaveListModel

Both are very similar, the only difference is the way how they retrieve their 
data. For this reason I created a base class BaseListModel and derived both
SqlListModel and SlaveListModel.

The base class has an attribute "select_list", which holds the list with the 
SQLObject instances.

Now if I use one instance of SqlListModel (for showing the data from one 
table) and one instance of SlaveListModel (for showing data from a 1:n 
relation), in the SlaveListModel appears data from the SqlListModel.

Just to give it a try, I moved teh attribute "select_list" to the subclasses 
(SqlListModel and SlaveListModel), and the problem disappeared - as long as I 
only use one instance of each. 

I suspect, that the problem arises when any instance clears rows from the list 
to populate it with new rows. So I simply added 

self.select_list = []

at the end of the method that evacuates the list and things seem to work 
(until now).

The whole method is:

    def evacuate(self):
        num_items = len(self.select_list)
        for i in range(num_items):
            last_path = num_items-(i+1)
            my_iter = self.get_iter(last_path)
            row = self.get_row(my_iter)
            self.select_list.remove(row)
            self.row_deleted(last_path)
        self.select_list = [] #<=UGLY

However I think that the problem seems to point to a (heavy) leakage of iters, 
and I really do not understand why this happens. Anyone any idea?


More information about the pygtk mailing list