~ubuntu-branches/ubuntu/utopic/python-traitsui/utopic

« back to all changes in this revision

Viewing changes to examples/tutorials/traitsui_4.0/items.py

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2011-07-09 13:57:39 UTC
  • Revision ID: james.westby@ubuntu.com-20110709135739-x5u20q86huissmn1
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#  Copyright (c) 2007, Enthought, Inc.
 
2
#  License: BSD Style.
 
3
 
 
4
#--(Extended Traits UI Item and Editor References)------------------------------
 
5
"""
 
6
Extended Traits UI Item and Editor References
 
7
=============================================
 
8
 
 
9
In Traits 3.0, the Traits UI **Item** class and various *editor* classes
 
10
have been extended to use the new extended trait name support provided by the
 
11
*on_trait_change* method.
 
12
 
 
13
In previous Traits versions, for example, **Item** objects could only refer to
 
14
traits defined directly on a UI context object. For example::
 
15
 
 
16
    view = View(
 
17
        Item( 'name' ),
 
18
        Item( 'object.age' ),
 
19
        Item( 'handler.status' )
 
20
    )
 
21
 
 
22
In Traits 3.0 this restriction has been lifted, and now **Items** can reference
 
23
(i.e. edit) any trait reachable from a UI context object::
 
24
 
 
25
    view = View(
 
26
        Item( 'object.mother.name' ),
 
27
        Item( 'object.axel.chassis.serial_number', style = 'readonly' )
 
28
    )
 
29
 
 
30
Similarly, any Traits UI *editor* classes that previously accepted a trait name
 
31
now accept an extended trait name::
 
32
 
 
33
    view = View(
 
34
        Item( 'address' ),
 
35
        Item( 'state', editor = EnumEditor( name = 'handler.country.states' )
 
36
    )
 
37
 
 
38
Because **Items** and *editors* only refer to a single trait, you should not use
 
39
extended trait references that refer to multiple traits, such as
 
40
*'foo.[bar,baz]'* or *'foo.+editable'*, since the behavior of such references
 
41
is not defined.
 
42
 
 
43
Look at the code tabs for this lesson for a complete example of a Traits UI
 
44
using extended **Item** and editor references. In particular, the
 
45
**LeagueModelView Class** tab contains a **View** definition containing
 
46
extended references.
 
47
 
 
48
Code Incompatibilities
 
49
----------------------
 
50
 
 
51
Note that the editor enhancement may cause some incompatibities with editors
 
52
that previously supported both an *object* and *name* trait, with the *object*
 
53
trait containing the context object name, and the *name* trait containing the
 
54
name of  the trait on the specified context object. Using the new extended trait
 
55
references, these have been combined into a single *name* trait.
 
56
 
 
57
If you encounter such an occurrence in existing code, simply combine the
 
58
context object name and trait name into a single extended name of the form::
 
59
 
 
60
    context_object_name.trait_name
 
61
 
 
62
Warning
 
63
-------
 
64
 
 
65
Avoid extended **Item** references that contain intermediate links that could
 
66
be *None*. For example, in the following code::
 
67
 
 
68
    view = View(
 
69
        ...
 
70
        Item( 'object.team.players', ... )
 
71
        ...
 
72
    )
 
73
 
 
74
an exception will be raised if *object.team* is *None*, or is set to *None*,
 
75
while the view is active, since there is no obvious way to obtain a valid value
 
76
for *object.team.players* for the associated **Item** *editor* to display.
 
77
 
 
78
Note that the above example is borrowed from this lesson's demo code, which has
 
79
additional code written to ensure that *object.team* is not *None*. See the
 
80
*_model_changed* method in the **LeagueModelView Class** tab, which makes sure
 
81
that the *team* trait is intialized to a valid value when a new **League**
 
82
model is set up.
 
83
"""
 
84
 
 
85
#--<Imports>--------------------------------------------------------------------
 
86
 
 
87
from traits.api \
 
88
    import *
 
89
 
 
90
from traitsui.api \
 
91
    import *
 
92
 
 
93
from traitsui.table_column \
 
94
    import *
 
95
 
 
96
#--[Player Class]---------------------------------------------------------------
 
97
 
 
98
# Define a baseball player:
 
99
class Player ( HasTraits ):
 
100
 
 
101
    # The name of the player:
 
102
    name = Str( '<new player>' )
 
103
 
 
104
    # The number of hits the player made this season:
 
105
    hits = Int
 
106
 
 
107
#--[Team Class]-----------------------------------------------------------------
 
108
 
 
109
# Define a baseball team:
 
110
class Team ( HasTraits ):
 
111
 
 
112
    # The name of the team:
 
113
    name = Str( '<new team>' )
 
114
 
 
115
    # The players on the team:
 
116
    players = List( Player )
 
117
 
 
118
    # The number of players on the team:
 
119
    num_players = Property( depends_on = 'players' )
 
120
 
 
121
    def _get_num_players ( self ):
 
122
        """ Implementation of the 'num_players' property.
 
123
        """
 
124
        return len( self.players )
 
125
 
 
126
#--[League Class]---------------------------------------------------------------
 
127
 
 
128
# Define a baseball league model:
 
129
class League ( HasTraits ):
 
130
 
 
131
    # The name of the league:
 
132
    name = Str( '<new league>' )
 
133
 
 
134
    # The teams in the league:
 
135
    teams = List( Team )
 
136
 
 
137
#--[LeagueModelView Class]-----------------------------------------------------
 
138
 
 
139
# Define a ModelView for a League model:
 
140
class LeagueModelView ( ModelView ):
 
141
 
 
142
    # The currently selected team:
 
143
    team = Instance( Team )
 
144
 
 
145
    # The currently selected player:
 
146
    player = Instance( Player )
 
147
 
 
148
    # Button to add a hit to the current player:
 
149
    got_hit = Button( 'Got a Hit' )
 
150
 
 
151
    # The total number of hits
 
152
    total_hits = Property( depends_on = 'model.teams.players.hits' )
 
153
 
 
154
    @cached_property
 
155
    def _get_total_hits ( self ):
 
156
        """ Returns the total number of hits across all teams and players.
 
157
        """
 
158
        return 0
 
159
        return reduce( add, [ reduce( add, [ p.hits for p in t.players ], 0 )
 
160
                              for t in self.model.teams ], 0 )
 
161
 
 
162
    view = View(
 
163
        VGroup(
 
164
            HGroup(
 
165
                Item( 'total_hits', style = 'readonly' ),
 
166
                      label       = 'League Statistics',
 
167
                      show_border = True
 
168
            ),
 
169
            VGroup(
 
170
                Item( 'model.teams',
 
171
                      show_label = False,
 
172
                      editor = TableEditor(
 
173
                                columns = [ ObjectColumn( name  = 'name',
 
174
                                                          width = 0.70 ),
 
175
                                            ObjectColumn( name  = 'num_players',
 
176
                                                          label = '# Players',
 
177
                                                          editable = False,
 
178
                                                          width = 0.29 ) ],
 
179
                                selected     = 'object.team',
 
180
                                auto_add     = True,
 
181
                                row_factory  = Team,
 
182
                                configurable = False,
 
183
                                sortable     = False )
 
184
                ),
 
185
                label       = 'League Teams',
 
186
                show_border = True
 
187
            ),
 
188
            VGroup(
 
189
                Item( 'object.team.players', # <-- Extended Item name
 
190
                      show_label = False,
 
191
                      editor = TableEditor(
 
192
                                   columns  = [ ObjectColumn( name  = 'name',
 
193
                                                              width = 0.70 ),
 
194
                                                ObjectColumn( name  = 'hits',
 
195
                                                              editable = False,
 
196
                                                              width = 0.29 ) ],
 
197
                                   selected     = 'object.player',
 
198
                                   auto_add     = True,
 
199
                                   row_factory  = Player,
 
200
                                   configurable = False,
 
201
                                   sortable     = False )
 
202
                ),
 
203
                '_',
 
204
                HGroup(
 
205
                    Item( 'got_hit',
 
206
                          show_label   = False,
 
207
                          enabled_when = 'player is not None'
 
208
                    )
 
209
                ),
 
210
                label       = 'Team Players',
 
211
                show_labels = False,
 
212
                show_border = True
 
213
            )
 
214
        ),
 
215
        resizable = True
 
216
    )
 
217
 
 
218
    def _model_changed ( self, model ):
 
219
        """ Handles the 'league' model being initialized.
 
220
        """
 
221
        if len( model.teams ) > 0:
 
222
            self.team = model.teams[0]
 
223
 
 
224
    def _got_hit_changed ( self ):
 
225
        """ Handles the currently selected player making a hit.
 
226
        """
 
227
        self.player.hits += 1
 
228
 
 
229
    def _team_changed ( self, team ):
 
230
        """ Handles a new team being selected.
 
231
        """
 
232
        if len( team.players ) > 0:
 
233
            self.player = team.players[0]
 
234
        else:
 
235
            self.player = None
 
236
 
 
237
# Function to add two numbers (used with 'reduce'):
 
238
add = lambda a, b: a + b
 
239
 
 
240
#--[Example*]-------------------------------------------------------------------
 
241
 
 
242
# Define some sample teams and players:
 
243
blue_birds = Team( name = 'Blue Birds', players = [
 
244
    Player( name = 'Mike Scott',     hits = 25 ),
 
245
    Player( name = 'Willy Shofield', hits = 37 ),
 
246
    Player( name = 'Tony Barucci',   hits = 19 ) ] )
 
247
 
 
248
chicken_hawks = Team( name = 'Chicken Hawks', players = [
 
249
    Player( name = 'Jimmy Domore',   hits = 34 ),
 
250
    Player( name = 'Bill Janks',     hits = 16 ),
 
251
    Player( name = 'Tim Saunders',   hits = 27 ) ] )
 
252
 
 
253
eagles = Team( name = 'Eagles', players = [
 
254
    Player( name = 'Joe Peppers',    hits = 33 ),
 
255
    Player( name = 'Sam Alone',      hits = 12 ),
 
256
    Player( name = 'Roger Clemson',  hits = 23 ) ] )
 
257
 
 
258
# Create a league and its corresponding model view:
 
259
demo = LeagueModelView(
 
260
    League( name  = 'National Baseball Conference',
 
261
            teams = [ blue_birds, chicken_hawks, eagles ] )
 
262
)
 
263