File: model_view.py

package info (click to toggle)
python-traitsui 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 13,292 kB
  • sloc: python: 39,867; makefile: 120; sh: 5
file content (152 lines) | stat: -rw-r--r-- 5,462 bytes parent folder | download
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 )