1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
# Copyright (c) 2007, Enthought, Inc.
# License: BSD Style.
#--(ModelView and Controller Classes)-------------------------------------------
"""
ModelView and Controller Classes
================================
Traits 3.0 introduces two new **Handler** subclasses, **ModelView** and
**Controller**, both of which are intended to help simplify the process of
creating MVC (i.e. Model/View/Controller) based applications.
Both **Controller** and **ModelView** classes add the following new traits to
the **Handler** subclass::
# The model this handler defines a view and controller for:
model = Instance( HasTraits )
# The UIInfo object associated with the controller:
info = Instance( UIInfo )
The *model* trait provides simple access to the model object associated with
either the **Controller** or **ModelView** class. Normally, the *model* trait
is set in the constructor when a **Controller** or **ModelView** subclass is
created. See the **Example** tab for an example of this.
The *info* trait provides access to the **UIInfo** object associated with the
active user interface view for the handler object. The *info* trait is set
automatically when the handler's object view is created.
So far, the **Controller** and **ModelView** classes are identical. The only
difference between them is in the *context* dictionary each class defines when
it creates it associated user interface.
For a **Controller** subclass, the *context* dictionary contains:
object
The **Controller**'s *model* object.
controller
The **Controller** object itself.
For a **ModelView** subclass, the *context* dictionary contains:
object
The **ModelView** object itself.
model
The **ModelView**'s *model* object.
The **Controller** class is normally used when implementing a standard MVC-based
design. In this case, the *model* object contains most, if not all, of the data
being viewed, and can be easily referenced in the controller's **View**
definition using unqualified trait names (e.g. *Item( 'name' )*).
The **ModelView** class is useful when creating a variant of the standard
MVC-based design the author likes to refer to as a *model-view*. In this
pattern, the **ModelView** subclass typically reformulates a number of the
traits on its associated *model* object as properties on the **ModelView**
class, usually for the purpose of converting the model's data into a more user
interface friendly format.
So in this design, the **ModelView** class not only supplies the view and
controller, but also, in effect, the model (as a set of properties wrapped
around the original model). Because of this, the **ModelView** context
dictionary specifies itself as the special *object* value, and assigns the
original model as the *model* value. Again, the main purpose of this is to
allow easy reference to the **ModelView**'s property traits within its **View**
using unqualified trait names.
Other than these somewhat subtle, although useful, distinctions, the
**Controller** and **ModelView** classes are identical, and which class to use
is really a personal preference as much as it is a design decision.
Calling the Constructor
-----------------------
Both the **ModelView** and **Controller** classes have the same constructor
signature::
ModelView( model = None, **metadata )
Controller( model = None, **metadata )
So both of the following are valid examples of creating a controller for
a model::
mv = MyModelView( my_model )
c = MyController( model = my_model )
An Example
----------
The code portion of this lesson provides a complete example of using a
**ModelView** design. Refer to the lesson on *Delegation Fixes and Improvements*
for an example of a related **Controller** based design.
"""
#--<Imports>--------------------------------------------------------------------
from traits.api import *
from traitsui.api import *
from traitsui.table_column import *
#--[Parent Class]---------------------------------------------------------------
class Parent ( HasTraits ):
first_name = Str
last_name = Str
#--[Child Class]----------------------------------------------------------------
class Child ( HasTraits ):
mother = Instance( Parent )
father = Instance( Parent )
first_name = Str
last_name = Delegate( 'father' )
#--[ChildModelView Class]-------------------------------------------------------
class ChildModelView ( ModelView ):
# Define the 'family' ModelView property that maps the child and its
# parents into a list of objects that can be viewed as a table:
family = Property( List )
# Define a view showing the family as a table:
view = View(
Item( 'family',
show_label = False,
editor = TableEditor(
columns = [ ObjectColumn( name = 'first_name' ),
ObjectColumn( name = 'last_name' ) ] ) ),
resizable = True
)
# Implementation of the 'family' property:
def _get_family ( self ):
return [ self.model.father, self.model.mother, self.model ]
#--[Example*]-------------------------------------------------------------------
# Create a sample family:
mom = Parent( first_name = 'Julia', last_name = 'Wilson' )
dad = Parent( first_name = 'William', last_name = 'Chase' )
son = Child( mother = mom, father = dad, first_name = 'John' )
# Create the controller for the model:
demo = ChildModelView( model = son )
|