Hi everyone. This doubt needs guru helping :s.<br><br>I'll try to be quick and clear. I'm creating a ComboBoxEntry and binding some signals to a function I've coded myself:<br><br><i>comboboxentry = gtk.ComboBoxEntry(listmodel, 0)<br>
comboboxentry.connect('editing-done', self.on_change)<br>comboboxentry.connect('focus-out-event', self.on_change)</i><br><br>Method on_change is declared as:<br><br><i>def on_change(self, widget, data=None):</i><br clear="all">
<br>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.<br>
<br>Well, I hope someone could help me, but this is (or seems to be) an obscure problem :S.<br><br><b>NOW I WILL POST (PART OF) MY CODE BUT I HOPE YOU DONT NEED TO (NOT TOO MUCH) SEE IT BECAUSE IS VERY UGLY</b><br><br>---------------------------------------------------------------------------------------------------------------------------<br>
- In the A.py file:<br><br># 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.<br><i>#<u><b>type</b></u></i><i> = field.<u><b>FieldWithValues</b></u>(TYPE_N, TYPE_L, TYPE_VALUES)<br>
<u><b>type</b></u> = field.<b><u>Field</u></b>(TYPE_N, TYPE_L)<br>...<br># code is a multformatfield which depends on type<br>code = field.<u><b>MultiformatField</b></u>(relation, <b><u>type</u></b>)</i><br><br>- In the field.py file (the one which implements Field and MultiformatField):<i><br>
<br>class <u><b>Field</b></u>(): <br> def __init__(self, name, length):<br> self._name = name<br> self._length = length<br> self._hooks = []<br> ...<br><br> def <u><b>set_hook</b></u>(self, hook):<br>
self._hooks.append(hook)<br><br> def <u><b>get_hooks</b></u>(self):<br> return self._hooks<br><br>class </i><i><u><b>MultiformatField</b></u>(Field):<br> def __init__(self, relation, <u><b>field</b></u>):<br>
self._relation = relation<br> <u><b>self._depend_field = field</b></u></i><br><i> ...<br><br> def <u><b>get_dependency_field</b></u>(self):<br> return <u><b>self._depend_field</b></u></i><br><br>
<br>- type and code are used later to create FieldView and MultiformatFieldView, these "views" are implemented in other file:<br><br>class BaseFieldView():<br> def __init__(self, <u><i><b>model</b></i></u>):<br>
<u><i><b>self._model = model</b></i></u><br><br> ...<br> def <u><i><b>on_change</b></i></u>(self, widget, data=None):<br> print 'on_change called ' + str(self) + ' with model ' + str(<u><i><b>self._model</b></i></u>)<br>
for pair in self._model.<u><i><b>get_hooks</b></i></u>():<br> pair[0](value)<br> ...<br><br><i>class <u><b>FieldView</b></u>(gtk.Frame, <u><b>BaseFieldView</b></u>):<br> def __init__(self, <u><b>model</b></u>):<br>
gtk.Frame.__init__(self, model.get_name())<br> <u><b>BaseFieldView.__init__(self, model)</b></u><br> entry = gtk.Entry()<br> self.add(entry)<br> <u><b>entry.connect('activate', self.on_change)<br>
</b></u></i> <i><u><b>entry.connect('focus-out-event', self.on_change)</b></u></i><br>...<br><i><br>class <u><b>FieldWithValuesView</b></u>(gtk.Frame, <u><b>BaseFieldView</b></u>):<br> def __init__(self, model):<br>
gtk.Frame.__init__(self, model.get_name())<br> <u><b>BaseFieldView.__init__(self, model)</b></u><br> listmodel = gtk.ListStore(gobject.TYPE_STRING)<br> column = []<br> for elem in model.get_map_names():<br>
column.append(elem)<br> column.sort()<br> for elem in column:<br> listmodel.append((elem,))<br> comboboxentry = gtk.ComboBoxEntry(listmodel, 0)<br><b> <u>comboboxentry.connect('editing-done', self.on_change)</u><br>
<u>comboboxentry.connect('focus-out-event', self.on_change)</u></b></i><br>...<br><br>class <u><i><b>MultiformatFieldView</b></i></u>(gtk.VBox, <u><i><b>BaseFieldView</b></i></u>):<br> def __init__(self, model):<br>
gtk.VBox.__init__(self, spacing=DEF_SPACING)<br> <u><i><b>BaseFieldView.__init__(self, model)</b></i></u><br> <br> dep_field = model.<u><i><b>get_dependency_field()</b></i></u><br> dep_field.<u><i><b>set_hook</b></i></u>(self.change_view)<br>
print 'creating multiformatfieldview ' + str(self) + ' an its model is ' + str(dep_field)<br> ...<br><br>---------------------------------------------------------------------------------------------------------------------------<br>
<br>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.<br>
<br>With other words:<br><br>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).<br>
<br>So i will explain the problem again:<br><br>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.<br>
<br>Ey, if you have really readed all of that... sorry about my poor english :-$, you really have balls (even if you are a woman!).<br><br>I'm really really thanksful about this mailing list. Thanks all of you.<br><br>
<br><br>-- <br>David<br>