Hi all,

I know that this topic came up a few times, but I couldn't find a
working solution across the net yet. Maybe someone here on the list
could point me in the right direction...

I'm about to port a GTK2 application to GTK3. Within this application
I've got a simple GenericTreeModel that causes me headaches when I try
to port it.

To understand things better, I've wrote a stripped down version.
Here's the GenericTreeModel variant, that takes in a simple list of
values:

import gtk, gobject

class TreeModel(gtk.GenericTreeModel):

    def __init__(self, data):
        self.data = data
        super(TreeModel, self).__init__()

    def on_get_n_columns(self):
        return 1

    def on_get_column_type(self, idx):
        return gobject.TYPE_PYOBJECT

    def on_get_iter(self, path):
        if path[0] < len(self.data):
            return path[0]
        else:
            return None

    def on_iter_next(self, iter_):
        if iter_ < len(self.data) - 1:
            return iter_ + 1
        else:
            return None

    def on_get_value(self, iter_, column):
        return self.data[iter_]


if __name__ == '__main__':
    t = TreeModel(['foo', 'bar', 'baz'])
    iter_ = t.get_iter_first()
    while iter_:
        print(t.get_value(iter_, 0))
        iter_ = t.iter_next(iter_)

This code works as expected and outputs "foo", "bar", "baz". As you
can see, I'm using simple list indices as iter.

My first attempt in porting it to TreeModel looks like this:

from gi.repository import Gtk, GObject

class TreeModel(GObject.GObject, Gtk.TreeModel):

    def __init__(self, data):
        self.data = data
        super(TreeModel, self).__init__()

    def do_get_n_columns(self):
        return 1

    def do_get_column_type(self, idx):
        return GObject.TYPE_PYOBJECT

    def do_get_iter(self, path):
        ### path is now TreePath ###
        p = path.get_indices()
        if p[0] < len(self.data):
            return p[0]
        else:
            return None

    def do_iter_next(self, iter_):
        if iter_ < len(self.data) - 1:
            return iter_ + 1
        else:
            return None

    def do_get_value(self, iter_, column):
        return self.data[iter_]

When running the same main function as above, the following error is
raised (on Debian testing):

ERROR:/home/martin/debian/pkg-gnome/build-area/pygobject-3.2.2/gi/pygi-closure.c:317:_pygi_closure_set_out_arguments:
code should not be reached

Somewhere I've found that do_get_iter() should return a 2-tuple, when
changing the above code to

    def do_get_iter(self, path):
        # path is now TreePath
        p = path.get_indices()
        if p[0] < len(self.data):
            return (True, p[0])
        else:
            return (False, None)

the following traceback is raised:

Traceback (most recent call last):
  File "treemodelgi2.py", line 34, in do_get_value
    return self.data[iter_]
TypeError: list indices must be integers, not TreeIter

Somewhere the 2-tuple returned by do_get_iter() is casted to a
TreeIter. But where is the list index (here p[0]) I've returned as my
iter? TreeIter.user_data is None in do_get_value(). Even when I return
a TreeIter directly in do_get_iter() with TreeIter.user_data set to
p[0] the information in user_data is lost when do_get_value() is
called since do_get_value() receives a different instance of TreeIter
then.

Can anybod give me a hint on how to correctly port this simple custom
TreeModel? I'm kind of stuck now...

Best regards,

Andi
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to