Emanuele Olivetti <[EMAIL PROTECTED]> writes:
> Thanks for all the answers, now I have many solutions for my
> problem. But, is there a way to avoid the explicit notification
> to the view following the model view controller pattern?
> Can a view autonomously update when an asynchronous event changes
> the model?
The answer is yes and no. In common usage it looks like a change to
the model automagically notifies the view, but underneath somewhere
there is always an explicit emit() that sends the signal. If you
update the model using the gtk+ provided calls xxx_store_set_value(),
xxx_store_insert() and the like the gtk+ library will emit the
"row_changed" signal for you. If you modify the model any other way
then you are responsible to emit the signal. This is true in the C
bindings as well as in pygtk.
If you look at your change() callback
def change(button, people):
"""Swap name and surname of all people"""
for i in people:
tmp=i.name
i.name=i.surname
i.surname=tmp
you are updating attributes of instances of the Person class directly.
You know that you intend to update a treemodel, but this isn't
explicit in the code at all.
You can make this work. Instead of passing a Python list to the
change() callback
b.connect("clicked",change,people)
instead pass the model like this
b.connect("clicked",change,model)
Now the change() callback can explicitly update the model. You
could write this many ways. One way is
def change(button, model):
"""Swap name and surname of all people"""
for row in model:
person = row[0]
swapped_person = Person(person.surname, person.name)
row[0] = swapped_person
The magic is the row[0] = ... bit since it gives pygtk enough
information so that it knows the model has changed. If you want to
update the instances in place as in your example code you can do that
too, although it will look odd
def change(button, model):
"""Swap name and surname of all people"""
for row in model:
person = row[0]
tmp = person.name
person.name = person.surname
person.surname = tmp
row[0] = person
The row[0] = person bit looks strange but without it pygtk doesn't see
the change to the model. (Under the covers row[0] = ... will invoke
gtk_list_store_set().) Instead it's better to just use
model.row_changed(row.path, row.iter)
since it is more explicit.
These subtleties can be avoided by using treestores using only
standard gtk+ types. If you create your ListStore with two
gobject.TYPE_STRING like this:
model = gtk.ListStore(str, str)
and replace the cell_data_func parts with the appropriate treecolumn
definitions, the change() callback would look like this
def change(button, model):
"""Swap name and surname of all people"""
for row in model:
tmp = row[0]
row[0] = row[1]
row[1] = row[0]
This makes your intentions clear to pygtk and it will emit
"row-changed" signals for you.
_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/