David McCabe <[EMAIL PROTECTED]> writes:

> Um...the whole point of backing the TreeModel with a list subclass was
> because I didn't want to deal with the horrid Tree API anymore. And
> using it did make my code vastly cleaner than when I was dealing with
> TreeModel directly.
>
> Or do I misunderstand you?

Yeah, you don't have to use the TreeModel API everywhere.  You just
use the TreeModel API in a few methods in the list subclass. (I think
this is required in any case, since we need to update the TreeModel
from the backing list.)  Outside those methods, you can use the Python
list API.

Here is a really ugly example, presented with no comments and some
poorly chosen class, function and variable names .  It isn't even
close to production quality, but it's fairly short.  (The tlist class
needs a lot of work.  Its __init__() method should take an initializer
sequence argument.  The __setitem__() method doesn't handle slices
correctly.  More methods like extend(), pop(), reverse() and sort()
should be implemented, or at least trapped to raise an exception if
they aren't implemented.  Other general ugliness abounds in the rest
of the example.)

The point is that the our_list variable can be treated as a Python
list outside the tlist class.  In particular, notice that
on_add_button_clicked(), on_sub_button_clicked() and
on_double_button_clicked() use the user_data parm (which is our_list)
as a Python list, without knowing that there is an underlying
TreeModel.

[I put some extra code in the __delitem__() method because it seems
that the pygtk ListStore binding doesn't accept negative indices.
This makes it's API diverge a bit from the Python sequence API.  I
don't know if this was intentional or not.]


class tlist(list):
    def __init__(self):
        list.__init__(self)
        self.model = gtk.ListStore(object)
        self.model.connect('row-inserted', self.on_row_inserted)
        self.model.connect('row-changed', self.on_row_changed)
        self.model.connect('row-deleted', self.on_row_deleted)

    def append(self, value):
        self.model.append((value,))

    def __setitem__(self, key, value):
        self.model[key][0] = value

    def __delitem__(self, key):
        if key < 0:
            key += len(self.model)
        del self.model[key]

    def on_row_inserted(self, model, path, treeiter):
        list.insert(self, path[0], model[path][0])

    def on_row_changed(self, model, path, treeiter):
        list.__setitem__(self, path[0], model[path][0])

    def on_row_deleted(self, model, path):
        list.__delitem__(self, path[0])

def cell_data_func(treecolumn, cell, treemodel, treeiter):
    cell.set_property('text', str(treemodel.get_value(treeiter, 0)))

win = gtk.Window()
win.connect('delete-event', gtk.mainquit)
vb = gtk.VBox()
win.add(vb)
add_button = gtk.Button('Add One')
vb.pack_start(add_button, False, False, False)
sub_button = gtk.Button('Remove One')
vb.pack_start(sub_button, False, False, False)
double_button = gtk.Button('Double')
vb.pack_start(double_button, False, False, False)

sw = gtk.ScrolledWindow()
vb.pack_start(sw, True, True, True)

tv = gtk.TreeView()
sw.add(tv)

tv.insert_column_with_data_func(
    -1, 'N', gtk.CellRendererText(), cell_data_func)

our_list = tlist()
tv.set_model(our_list.model)

for i in range(10):
    our_list.append(i)

def on_add_button_clicked(button, user_data):
    if len(user_data) > 0:
        user_data.append(user_data[-1]+1)
    else:
        user_data.append(0)

def on_sub_button_clicked(button, user_data):
    if len(user_data) > 0:
        del user_data[-1]

def on_double_button_clicked(button, user_data):
    for i in range(len(user_data)):
        user_data[i] *= 2

add_button.connect('clicked', on_add_button_clicked, our_list)
sub_button.connect('clicked', on_sub_button_clicked, our_list)
double_button.connect('clicked', on_double_button_clicked, our_list)

win.show_all()
gtk.main()

_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to