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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
|
.. index:: View; customizing
.. _customizing-a-view:
==================
Customizing a View
==================
As shown in the preceding two chapters, it is possible to specify a window in
TraitsUI simply by creating a View object with the appropriate contents. In
designing real-life applications, however, you usually need to be able to
control the appearance and behavior of the windows themselves, not merely their
content. This chapter covers a variety of options for tailoring the appearance
of a window that is created using a View, including the type of window that a
View appears in, the :term:`command button`\ s that appear in the window, and
the physical properties of the window.
.. index:: kind attribute
.. _specifying-window-type-the-kind-attribute:
Specifying Window Type: the **kind** Attribute
----------------------------------------------
Many types of windows can be used to display the same data content. A form can
appear in a window, a wizard, or an embedded panel; windows can be *modal*
(i.e., stop all other program processing until the box is dismissed) or not, and
can interact with live data or with a buffered copy. In TraitsUI, a single View
can be used to implement any of these options simply by modifying its **kind**
attribute. There are seven possible values of **kind**:
.. index:: modal; window kind, live; window kind, livemodal window kind
.. index:: nonmodal window kind, wizard; window kind, panel; window kind
.. index:: subpanel; window kind
* 'modal'
* 'live'
* 'livemodal'
* 'nonmodal'
* 'wizard'
* 'panel'
* 'subpanel'
These alternatives are described below. If the **kind** attribute of a View
object is not specified, the default value is 'modal'.
.. index:: windows; stand-alone, modal; definition, live; definition
.. _stand-alone-windows:
Stand-alone Windows
```````````````````
The behavior of a stand-alone TraitsUI window can vary over two significant
degrees of freedom. First, it can be :term:`modal`, meaning that when the window
appears, all other GUI interaction is suspended until the window is closed; if
it is not modal, then both the window and the rest of the GUI remain active and
responsive. Second, it can be :term:`live`, meaning that any changes that the
user makes to data in the window is applied directly and immediately to the
underlying model object or objects; otherwise the changes are made to a copy of
the model data, and are only copied to the model when the user commits them
(usually by clicking an :guilabel:`OK` or :guilabel:`Apply` button; see
:ref:`command-buttons-the-buttons-attribute`). The four possible combinations of
these behaviors correspond to four of the possible values of the 'kind '
attribute of the View object, as shown in the following table.
.. _matrix-of-traits-ui-windows-table:
.. rubric:: Matrix of TraitsUI windows
+-------------+----------------+-----------------+
| |not modal |modal |
+=============+================+=================+
|**not live** |:term:`nonmodal`|:term:`modal` |
+-------------+----------------+-----------------+
|**live** |:term:`live` |:term:`livemodal`|
+-------------+----------------+-----------------+
All of these window types are identical in appearance. Also, all types support
the **buttons** attribute, which is described in
:ref:`command-buttons-the-buttons-attribute`. Usually, a window with command
buttons is called a :term:`dialog box`.
.. TODO: Add diagrams and/or examples to clarify.
.. index:: wizard, windows; wizard
.. _wizards:
Wizards
```````
Unlike a window, whose contents generally appear as a single page or a tabbed
display, a :term:`wizard` is presented as a series of pages that a user must
navigate sequentially.
.. TODO: Add a reference to the section on the organization of Views via
Groups, once it's been added.
.. TODO: add code and screenshot for a simple tabbed display and of the same
View presented as a Wizard.
TraitsUI Wizards are always modal and live. They always display a standard
wizard button set; i.e., they ignore the **buttons** View attribute. In short,
wizards are considerably less flexible than windows, and are primarily suitable
for highly controlled user interactions such as software installation.
.. index:: panel, subpanel, windows; panel, windows; subpanel
.. _panels-and-subpanels:
Panels and Subpanels
````````````````````
Both dialog boxes and wizards are secondary windows that appear separately from
the main program display, if any. Often, however, you might need to create a
window element that is embedded in a larger display. For such cases, the
**kind** of the corresponding View object should be 'panel' or 'subpanel '.
A :term:`panel` is very similar to a window, except that it is embedded in a
larger window, which need not be a TraitsUI window. Like windows, panels
support the **buttons** View attribute, as well as any menus and toolbars that
are specified for the View (see :ref:`menus-and-menu-bars`). Panels are always
live and nonmodal.
A :term:`subpanel` is almost identical to a panel. The only difference is that
subpanels do not display :term:`command button`\ s even if the View specifies
them.
.. Do subpanels support menus and toolbars? If not, add this to the
documentation. (If so, why do they?)
.. index:: buttons; attribute
.. _command-buttons-the-buttons-attribute:
Command Buttons: the **buttons** Attribute
------------------------------------------
A common feature of many windows is a row of command buttons along the bottom of
the frame. These buttons have a fixed position outside any scrolled panels in
the window, and are thus always visible while the window is displayed. They are
usually used for window-level commands such as committing or cancelling the
changes made to the form data, or displaying a help window.
In TraitsUI, these command buttons are specified by means of the View object's
**buttons** attribute, whose value is a list of buttons to display. [6]_
Consider the following variation on Example 3:
.. index::
pair: examples; buttons
.. _example-4-using-a-view-object-with-buttons:
.. rubric:: Example 4: Using a View object with buttons
::
# configure_traits_view_buttons.py -- Sample code to demonstrate
# configure_traits()
from traits.api import HasTraits, Str, Int
from traitsui.api import View, Item
from traitsui.menu import OKButton, CancelButton
class SimpleEmployee(HasTraits):
first_name = Str
last_name = Str
department = Str
employee_number = Str
salary = Int
view1 = View(Item(name = 'first_name'),
Item(name = 'last_name'),
Item(name = 'department'),
buttons = [OKButton, CancelButton])
sam = SimpleEmployee()
sam.configure_traits(view=view1)
The resulting window has the same content as before, but now two buttons are
displayed at the bottom: :guilabel:`OK` and :guilabel:`Cancel`:
.. figure:: images/ui_for_ex4.jpg
:alt: Dialog box with three fields and OK and Cancel buttons.
Figure 4: User interface for Example 4
There are six standard buttons defined by TraitsUI. Each of the standard
buttons has matching a string alias. You can either import and use the button
names, or simply use their aliases:
.. index:: buttons; standard, UndoButton, ApplyButton, RevertButton, OKButton
.. index:: CancelButton
.. _command-button-aliases-table:
.. rubric:: Command button aliases
+--------------+---------------------------+
|Button Name |Button Alias |
+==============+===========================+
|UndoButton |'Undo' |
+--------------+---------------------------+
|ApplyButton |'Apply' |
+--------------+---------------------------+
|RevertButton |'Revert' |
+--------------+---------------------------+
|OKButton |'OK' (case sensitive!) |
+--------------+---------------------------+
|CancelButton |'Cancel' |
+--------------+---------------------------+
Alternatively, there are several pre-defined button lists that can be imported
from traitsui.menu and assigned to the buttons attribute:
.. index:: OKCancelsButtons, ModalButtons, LiveButtons
* OKCancelButtons = ``[OKButton, CancelButton ]``
* ModalButtons = ``[ ApplyButton, RevertButton, OKButton, CancelButton, HelpButton ]``
* LiveButtons = ``[ UndoButton, RevertButton, OKButton, CancelButton, HelpButton ]``
Thus, one could rewrite the lines in Example 4 as follows, and the
effect would be exactly the same::
from traitsui.menu import OKCancelButtons
buttons = OKCancelButtons
.. index:: NoButtons
The special constant NoButtons can be used to create a window or panel
without command buttons. While this is the default behavior, NoButtons can
be useful for overriding an explicit value for **buttons**. You can also specify
``buttons = []`` to achieve the same effect. Setting the **buttons** attribute
to an empty list has the same effect as not defining it at all.
It is also possible to define custom buttons and add them to the **buttons**
list; see :ref:`custom-command-buttons` for details.
.. index:: View; attributes, attributes; View
.. _other-view-attributes:
Other View Attributes
---------------------
.. index:: dock attribute; View, height attribute; View, icon attribute
.. index:: image attribute; View, item_theme attribute; View
.. index:: label_theme attribute; View, resizable attribute; View
.. index:: scrollable attribute, statusbar attribute, style attribute; View
.. index:: title attribute, width attribute; View, x attribute, y attribute
.. _attributes-of-view-by-category-table:
.. rubric:: Attributes of View, by category
+----------+---------------------+---------------------------------------------+
|Category |Attributes |Description |
+==========+=====================+=============================================+
|Window |* **dock** |These attributes control the visual |
|display |* **height** |properties of the window itself, regardless |
| |* **icon** |of its content. |
| |* **image** | |
| |* **item_theme** |.. index:: close_result attribute |
| |* **label_theme** |.. index:: handler attribute |
| |* **resizable** |.. index:: key_bindings attribute |
| |* **scrollable** |.. index:: menubar attribute |
| |* **statusbar** |.. index:: model_view attribute |
| |* **style** |.. index:: on_apply attribute |
| |* **title** |.. index:: toolbar attribute |
| |* **width** |.. index:: updated attribute |
| |* **x** |.. index:: content attribute; View |
| |* **y** |.. index:: drop_class attribute |
+----------+---------------------+---------------------------------------------+
|Command |* **close_result** |TraitsUI menus and toolbars are generally |
| |* **handler** |implemented in conjunction with custom |
| |* **key_bindings** |:term:`Handler`\ s; see |
| |* **menubar** |:ref:`menus-and-menu-bars` for details. The |
| |* **model_view** |**key_bindings** attribute references the set|
| |* **on_apply** |of global key bindings for the view. |
| |* **toolbar** | |
| |* **updated** |.. index:: export attribute; View |
| | |.. index:: imports attribute |
| | |.. index:: object attribute; View |
+----------+---------------------+---------------------------------------------+
|Content |* **content** |The **content** attribute is the top-level |
| |* **drop_class** |Group object for the view. The **object** |
| |* **export** |attribute is the object being edited. The |
| |* **imports** |**imports** and **drop_class** attributes |
| |* **object** |control what objects can be dragged and |
| | |dropped on the view. |
| | | |
| | |.. index:: help attribute; View |
| | |.. index:: help_id attribute; View |
+----------+---------------------+---------------------------------------------+
|User help |* **help** |The **help** attribute is a deprecated way to|
| |* **help_id** |specify that the View has a Help button. Use |
| | |the buttons attribute instead (see |
| | |:ref:`command-buttons-the-buttons-attribute` |
| | |for details). The **help_id** attribute is |
| | |not used by Traits, but can be used by a |
| | |custom help handler. |
| | | |
| | |.. index:: id attribute; View |
+----------+---------------------+---------------------------------------------+
|Unique |* **id** |The **id** attribute is used as a key to save|
|identifier| |user preferences about a view, such as |
| | |customized size and position, so that they |
| | |are restored the next time the view is |
| | |opened. The value of **id** must be unique |
| | |across all Traits-based applications on a |
| | |system. If no value is specified, no user |
| | |preferences are saved for the view. |
+----------+---------------------+---------------------------------------------+
.. rubric:: Footnotes
.. [6] Actually, the value of the **buttons** attribute is really a list of
Action objects, from which GUI buttons are generated by TraitsUI. The
Action class is described in :ref:`actions`.
|