Basically the user derives from class Model, and adds a class variable called __properties__ . This variable must be a map, whose elements' keys are names of properties, and the associated values are the intial values.
For example, suppose you want to create an OP called name initially associated to the value ``Rob'':
from gtkmvc.model import Model class MyModel (Model): __properties__ = { 'name' : 'Rob' } def __init__(self): Model.__init__(self) # ... return pass # end of class
That's all. By using a specific metaclass, property name will be automatically added, as well as all the code to handle it.
This means that you can use the property in this way:
m = MyModel() print m.name # prints 'Rob' m.name = 'Roberto' # changes the property value
What's missing is now an observer, to be notified when the property changes:
class AnObserver : def __init__(self, model): model.registerObserver(self) # ... return def property_name_change_notification(self, model, old, new): print ``Property name changed from '%s' to '%s''' % (old, new) return pass # end of class
The constructor gets an istance of a Model, and registers the class instance itself to the given model, to become an observer of that model instance.
To receive notifications for the property name, the observer must define a method called property_name_change_notification that when is automatically called will get the instance of the model containing the changed property, and the property's old and new values.
As you can see, an Observer is not required to derive from a specific class. Anyway, in the MVC framework models and mostly controllers are use also as observers.
Here follows an example of usage:
m = MyModel() o = AnObserver(m) print m.name # prints 'Rob' m.name = 'Roberto' # changes the property value, o is notified
Things so far are easy enough, but they get a bit complicated when you derive custom models from other custom models. For example, what happens to OP if you derive a new model class from the class MyModel?
In this case the behaviour of the OP trusty follows the typical Object Oriented rules:
For example:
from gtkmvc.model import Model class Test1 (Model): __properties__ = { 'prop1' : 1 } def __init__(self): Model.__init__(self) # this class is an observer of its own properties: self.registerObserver(self) return def property_prop1_change_notification(self, model, old, new): print "prop1 changed from '%s' to '%s'" % (old, new) return pass # end of class class Test2 (Test1): __properties__ = { 'prop2' : 2, 'prop1' : 3 } def __init__(self): Test1.__init__(self) # also this class is an observer of itself: self.registerObserver(self) return def property_prop2_change_notification(self, model, old, new): print "prop2 changed from '%s' to '%s'" % (old, new) return pass # test code: t1 = Test1() t2 = Test2() t2.prop2 = 20 t2.prop1 = 30 t1.prop1 = 10
When executed, this script generates this output:
prop2 changed from '2' to '20' prop1 changed from '3' to '30' prop1 changed from '1' to '10'
As you can see, t2.prop1 overrides the OP prop1 defined in Test1 (they have different intial values). Test2 could also override method property_prop1_change_notification:
class Test2 (Test1): # ... copy from previous definition, and add: def property_prop1_change_notification(self, model, old, new): print "Test2: prop1 changed from '%s' to '%s'" % (old, new) return pass
As you expect, the output in this case would be:
prop2 changed from '2' to '20' Test2: prop1 changed from '3' to '30' prop1 changed from '1' to '10'