Hi again!
PROBLEM SOLVE!. It is needed finally (after one whole day) make the question
to the mailing list to find out the problem.
If anyone has interest. The problem where that actually on_change is not
being called when a FieldWithValuesView (in essential a gtk.ComboBoxEntry)
change. This happens because the binding done during the initialisation of
the view (__init__ of FieldWithValuesView) where not correctly done. I bind
to 'activate' and 'focus-out-event', but i need to bind the on_change method
to the signals 'activate' and 'focus-out-event' of the gtk.Entry maintained
by the gtk.ComboBoxEntry, it is necessary to use the gtk.Entry inside de
combobox as if it were created by me. The entry is accesible by the child
attribute of the combobox. So the fix is:
class FieldWithValuesView(gtk.Frame, BaseFieldView):
def __init__(self, model):
gtk.Frame.__init__(self, model.get_name())
BaseFieldView.__init__(self, model)*
listmodel = gtk.ListStore(gobject.TYPE_STRING)
column = []
for elem in model.get_map_names():
column.append(elem)
column.sort()
for elem in column:
listmodel.append((elem,))
comboboxentry = gtk.ComboBoxEntry(listmodel, 0)
* comboboxentry.connect('editing-done', self.on_change)
comboboxentry.connect('focus-out-event', self.on_change)
* comboboxentry.connect('changed', self.on_change)
comboboxentry.child.connect('activate', self.on_change)
comboboxentry.child.connect('focus-out-event', self.on_change)*
Right now on_changed will be called when a value in the combo is selected,
when a value is directly put into the entry or when the entry lost the focus
or when the combo lost the focus.
Happy hacking.
--
David
2010/2/12 David López Luengo <[email protected]>
> Hi everyone. This doubt needs guru helping :s.
>
> I'll try to be quick and clear. I'm creating a ComboBoxEntry and binding
> some signals to a function I've coded myself:
>
> *comboboxentry = gtk.ComboBoxEntry(listmodel, 0)
> comboboxentry.connect('editing-done', self.on_change)
> comboboxentry.connect('focus-out-event', self.on_change)*
>
> Method on_change is declared as:
>
> *def on_change(self, widget, data=None):*
>
> The instances of this class has an attribute called _model (self._model)
> which is readed inside on_change, amazingly when i'm inside on_change the
> object contained in self._model has changed, I mean if during execution,
> self._model was at position 0x1ca11b8 (just an example), when i'm inside
> on_change the self._model it will be in other position instead of 0x1ca11b8.
> This is making me cry because if I don't use comboboxentries, instead of
> these, if i use gtk.Entries everything is as I think it should be. Inside
> on_change the self._model is in the same position.
>
> Well, I hope someone could help me, but this is (or seems to be) an obscure
> problem :S.
>
> *NOW I WILL POST (PART OF) MY CODE BUT I HOPE YOU DONT NEED TO (NOT TOO
> MUCH) SEE IT BECAUSE IS VERY UGLY*
>
>
> ---------------------------------------------------------------------------------------------------------------------------
> - In the A.py file:
>
> # Just one of these lines should be active at a time, if i use
> FieldWithValues, model is changing, but if i use Field, model is what it's
> suppose to be.
> *#type** = field.FieldWithValues(TYPE_N, TYPE_L, TYPE_VALUES)
> type = field.Field(TYPE_N, TYPE_L)
> ...
> # code is a multformatfield which depends on type
> code = field.MultiformatField(relation, type)*
>
> - In the field.py file (the one which implements Field and
> MultiformatField):*
>
> class Field():
> def __init__(self, name, length):
> self._name = name
> self._length = length
> self._hooks = []
> ...
>
> def set_hook(self, hook):
> self._hooks.append(hook)
>
> def get_hooks(self):
> return self._hooks
>
> class **MultiformatField(Field):
> def __init__(self, relation, field):
> self._relation = relation
> self._depend_field = field*
> * ...
>
> def get_dependency_field(self):
> return self._depend_field*
>
>
> - type and code are used later to create FieldView and
> MultiformatFieldView, these "views" are implemented in other file:
>
> class BaseFieldView():
> def __init__(self, *model*):
> *self._model = model*
>
> ...
> def *on_change*(self, widget, data=None):
> print 'on_change called ' + str(self) + ' with model ' + str(*
> self._model*)
> for pair in self._model.*get_hooks*():
> pair[0](value)
> ...
>
> *class FieldView(gtk.Frame, BaseFieldView):
> def __init__(self, model):
> gtk.Frame.__init__(self, model.get_name())
> BaseFieldView.__init__(self, model)
> entry = gtk.Entry()
> self.add(entry)
> entry.connect('activate', self.on_change)
> * *entry.connect('focus-out-event', self.on_change)*
> ...
> *
> class FieldWithValuesView(gtk.Frame, BaseFieldView):
> def __init__(self, model):
> gtk.Frame.__init__(self, model.get_name())
> BaseFieldView.__init__(self, model)
> listmodel = gtk.ListStore(gobject.TYPE_STRING)
> column = []
> for elem in model.get_map_names():
> column.append(elem)
> column.sort()
> for elem in column:
> listmodel.append((elem,))
> comboboxentry = gtk.ComboBoxEntry(listmodel, 0)
> comboboxentry.connect('editing-done', self.on_change)
> comboboxentry.connect('focus-out-event', self.on_change)*
> ...
>
> class *MultiformatFieldView*(gtk.VBox, *BaseFieldView*):
> def __init__(self, model):
> gtk.VBox.__init__(self, spacing=DEF_SPACING)
> *BaseFieldView.__init__(self, model)*
>
> dep_field = model.*get_dependency_field()*
> dep_field.*set_hook*(self.change_view)
> print 'creating multiformatfieldview ' + str(self) + ' an its model
> is ' + str(dep_field)
> ...
>
>
> ---------------------------------------------------------------------------------------------------------------------------
>
> I will try to explain in natural language what i'm trying. We have
> different kind of fields, some of them are very simple, are self-described,
> but other fields depends on the value of another field. Example: I have and
> object M that should be represented "like this" if object A has the value 3
> and "like that" if object A has the value 5. Each FieldView has its model
> (the Field-class instance). Essentialy each view is a gtk.Container which
> has an entry or something like an entry (gtk.Entry for FieldView and
> gtk.ComboBoxEntry for FieldWithValuesView). When a MultiformatField is
> created, is specified the Field instance of the dependency. Later we create
> the views of this fields. The view of type is easy since is allways the same
> (doesnt depends on nothing) but code depends on type. When code was created
> (as a MultiformatField) there was specified which format should be taken on
> which value (this is specified using "relation", it is just a dict of keys
> "values in type" and values "Field instances describing the format for that
> value in type"). When we create the MultiformatFieldView we say to the field
> "type" "ey man! when your view change its value execute this function please
> and give to it the value in your view", this is done calling to set_hook
> when creating the MultiformatFieldView. To make all of this work, we make
> that when type view is created its view (FieldView or FieldWithValuesView)
> bind the signals 'activate' and 'focus-out-event' or 'editing-done' and
> 'focus-out-event' (depending if FieldView or FieldWithValuesView since one
> used gtk.Entry and the other gtk.ComboBoxEntry and dont have same signals)
> to the function "on_change", which its only purpose is call one by one, all
> functions accumulated in the _hooks list of the model of the view.
>
> With other words:
>
> The views dont speak between them, each view only knows who is its model
> (self._model). Note that self._model is always a Field-like instance. Views
> allways call "on_change" when something changes inside it. On_change (a
> method of the views) knows about its own model (self._model) not of the
> MultiformatField, BUT, when MultiformatField is created this "depends on"
> field was specified and when MultiformatFieldView was created its __init__
> functions got the "depends on" field and install in its "hooks" list a
> function to exec (concretelly change_view).
>
> So i will explain the problem again:
>
> When I use type as Field everything goes fine, on_change takes self._model
> and is the same memory position as when MultiformatFieldView toke the
> "depends on" field. BUT when I use type as a FieldWithValues amazingly, when
> MultiformatFieldView is created, the "depends on" field is in a memory
> position and when on_change of the FieldWithValuesView is called its model
> (supposelly the same "depends on") is in other memory position. What is
> worse is that this "new" model has its hooks empty, i will dont care if this
> "new" model were an strictly copy of the "dissapeared" one, but it is not
> xDD.
>
> Ey, if you have really readed all of that... sorry about my poor english
> :-$, you really have balls (even if you are a woman!).
>
> I'm really really thanksful about this mailing list. Thanks all of you.
>
>
>
> --
> David
>
--
David
_______________________________________________
pygtk mailing list [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/