diff --git a/docs/source/api/traitsui.qt4.tree_node_renderers.rst b/docs/source/api/traitsui.editors.datetime_editor.rst similarity index 52% rename from docs/source/api/traitsui.qt4.tree_node_renderers.rst rename to docs/source/api/traitsui.editors.datetime_editor.rst index 84e53354c..d8b9966c7 100644 --- a/docs/source/api/traitsui.qt4.tree_node_renderers.rst +++ b/docs/source/api/traitsui.editors.datetime_editor.rst @@ -1,7 +1,7 @@ -traitsui\.qt4.tree\_node\_renderers module +traitsui\.editors\.datetime\_editor module ========================================== -.. automodule:: traitsui.qt4.tree_node_renderers +.. automodule:: traitsui.editors.datetime_editor :members: :undoc-members: :show-inheritance: diff --git a/docs/source/api/traitsui.editors.rst b/docs/source/api/traitsui.editors.rst index b21cefcb7..1996b5224 100644 --- a/docs/source/api/traitsui.editors.rst +++ b/docs/source/api/traitsui.editors.rst @@ -17,6 +17,7 @@ Submodules traitsui.editors.csv_list_editor traitsui.editors.custom_editor traitsui.editors.date_editor + traitsui.editors.datetime_editor traitsui.editors.default_override traitsui.editors.directory_editor traitsui.editors.dnd_editor diff --git a/docs/source/traitsui_user_manual/adapters.rst b/docs/source/traitsui_user_manual/adapters.rst index 4f9d32598..e03ab24ea 100644 --- a/docs/source/traitsui_user_manual/adapters.rst +++ b/docs/source/traitsui_user_manual/adapters.rst @@ -18,6 +18,7 @@ The TreeEditor and TreeNodes .. _tree-nodes: .. module:: traitsui.tree_node + :noindex: The :py:class:`~traitsui.editors.tree_editor.TreeEditor` internally associates with each node in the tree a pair consisting of the object that is associated @@ -305,6 +306,7 @@ The TabularAdapter Class ======================== .. module:: traitsui.tabular_adapter + :noindex: The power and flexibility of the tabular editor is mostly a result of the :py:class:`TabularAdapter` class, which is the base class from which all @@ -691,7 +693,7 @@ traits, where they can be easily accessed by a trait getter or setter method: - ``column``: The column id of the table column being accessed (not its index). - ``item``: The data item for the specified table row (i.e. the item determined in the first step described above). -- `value``: In the case of a *set_xxx* method, the value to be set; otherwise it +- ``value``: In the case of a *set_xxx* method, the value to be set; otherwise it is ``None``. As mentioned previously, the :py:class:`TabularAdapter` class provides trait @@ -857,6 +859,7 @@ The ListStrAdapter Class ======================== .. module:: traitsui.list_str_adapter + :noindex: Although the :py:class:`~traitsui.editors.list_str_editor.ListStrEditor` editor is frequently used, as might be expected, with lists of strings, it also diff --git a/docs/source/traitsui_user_manual/advanced_view.rst b/docs/source/traitsui_user_manual/advanced_view.rst index 5578290b0..37c6952b4 100644 --- a/docs/source/traitsui_user_manual/advanced_view.rst +++ b/docs/source/traitsui_user_manual/advanced_view.rst @@ -466,7 +466,7 @@ is not defined. Also, avoid extended trait references where one of the intermediate objects could be None, because there is no way to obtain a valid reference from None. -Refer to the `Traits User Manual `_, in the chapter on trait +Refer to the `Traits User Manual `_, in the chapter on trait notification, for details of the extended trait name syntax. .. index:: diff --git a/docs/source/traitsui_user_manual/custom_view.rst b/docs/source/traitsui_user_manual/custom_view.rst index fb466ad33..276e3889a 100644 --- a/docs/source/traitsui_user_manual/custom_view.rst +++ b/docs/source/traitsui_user_manual/custom_view.rst @@ -37,7 +37,7 @@ attribute. There are seven possible values of **kind**: * 'live' * 'livemodal' * 'nonmodal' -* 'wizard' +* 'wizard' (wx backend only) * 'panel' * 'subpanel' diff --git a/docs/source/traitsui_user_manual/factories_advanced_extra.rst b/docs/source/traitsui_user_manual/factories_advanced_extra.rst index fe73492b3..36cd20b1c 100644 --- a/docs/source/traitsui_user_manual/factories_advanced_extra.rst +++ b/docs/source/traitsui_user_manual/factories_advanced_extra.rst @@ -33,10 +33,6 @@ factory_function(*window_parent*, *editor*[, \*\ *args*, \*\*\ *kwargs*]) Additional arguments, if any, can be passed as a tuple in the *args* parameter of CustomEditor(). -For an example of using CustomEditor(),examine the implementation of the -NumericModelExplorer class in the enthought.model.numeric_model_explorer module; -CustomEditor() is used to generate the plots in the user interface. - DropEditor() ```````````` @@ -1267,43 +1263,23 @@ The following have special meaning for the DataFrameEditor(): - **fonts**: either a font for all entries, or a mapping of column id to fonts. -HistoryEditor() -``````````````` - -:Suitable for: - string traits -:Default for: - (none) -:Optional parameters: - *entries* - -HistoryEditor() generates a combo box, which allows the user to either enter a -text string or select a value from a list of previously-entered values. The same -control is used for all editor styles. The *entries* parameter determines how -many entries are preserved in the history list. This type of control is used as -part of the simple style of file editor; see :ref:`fileeditor`. - -ImageEditor() -````````````` +DefaultOverride() +````````````````` :Suitable for: (any) :Default for: (none) -:Optional parameters: - *image*, *scale*, *preserve_aspect_ratio*, *allow_upscaling*, - *allow_clipping* -ImageEditor() generates a read-only display of an image. The image to be -displayed is determined by the *image* parameter, or by the value of the trait -attribute being edited, if *image* is not specified. In either case, the value -must be a PyFace ImageResource (pyface.api.ImageResource), or a string -that can be converted to one. If *image* is specified, then the type and value -of the trait attribute being edited are irrelevant and are ignored. +The DefaultOverride() is a factory that takes the trait's default editor and +customizes it with the specified parameters. This is useful when a trait defines +a default editor using some of its data, e.g. Range or Enum, and you want to +tweak some of the other parameters without having recreate that data. + +For example, the default editor for Range(low=0, high=1500) has +'1500' as the upper label. To change it to 'Max' instead, use:: -For the Qt backend *scale*, *preserve_aspect_ratio*, *allow_upscaling*, and -*allow_clipping* control whether the image should be scaled or not, and how -to perform that scaling. + View(Item('my_range', editor=DefaultOverride(high_label='Max')) .. _extra-trait-editor-factories: @@ -1329,74 +1305,3 @@ AnimatedGIFEditor() AnimatedGIFEditor() generates a display of the contents of an animated GIF image file. The Boolean *playing* parameter determines whether the image is animated or static. - -FlashEditor() -````````````` - -:Suitable for: - string traits, Enum(string values) -:Default for: - (none) - -FlashEditor() generates a display of an Adobe Flash Video file, using an ActiveX -control (if one is installed on the system). This factory is available only on -Microsoft Windows platforms. The attribute being edited must have a value whose -text representation is the name or URL of a Flash video file. If the value is a -Unicode string, it must contain only characters that are valid for filenames or -URLs. - -IEHTMLEditor() -`````````````` - -:Suitable for: - string traits, Enum(string values) -:Default for: - (none) -:Optional parameters: - *back, forward, home, html, page_loaded, refresh, search, status, stop,* - *title* - -IEHTMLEditor() generates a display of a web page, using Microsoft Internet -Explorer (IE) via ActiveX to render the page. This factory is available only on -Microsoft Windows platforms. The attribute being edited must have value whose -text representation is a URL. If the value is a Unicode string, it must contain -only characters that are valid for URLs. - -The *back*, *forward*, *home*, *refresh*, *search* and *stop* parameters are -extended names of event attributes that represent the user clicking on the -corresponding buttons in the standard IE interface. The IE buttons are not -displayed by the editor; you must create buttons separately in the View, -if you want the user to be able to actually click buttons. - -The *html*, *page_loaded*, *status*, and *title* parameters are the extended -names of string attributes, which the editor updates with values based on its -own state. You can display these attributes elsewhere in the View. - -- *html*: The current page content as HTML (as would be displayed by the - :menuselection:`View > Source` command in IE). -- *page_loaded*: The URL of the currently displayed page; this may be different - from the URL represented by the attribute being edited. -- *status*: The text that would appear in the IE status bar. -- *title*: The title of the currently displayed page. - -LEDEditor() -``````````` - -:Suitable for: - numeric traits -:Default for: - (none) -:Optional parameters: - *alignment, format_str* - -LEDEditor() generates a display that resembles a "digital" display using -light-emitting diodes. All styles of this editor are the same, and are -read-only. - -The *alignment* parameter can be 'left', 'center', or 'right' to indicate how -the value should be aligned within the display. The default is right-alignment. - -.. figure:: images/led_editor.png - :alt: LED-like display of 90452 - - Figure 56: LED Editor with right alignment diff --git a/docs/source/traitsui_user_manual/factories_basic.rst b/docs/source/traitsui_user_manual/factories_basic.rst index 37b58a762..9e58f3355 100644 --- a/docs/source/traitsui_user_manual/factories_basic.rst +++ b/docs/source/traitsui_user_manual/factories_basic.rst @@ -45,10 +45,13 @@ ArrayEditor() *width* The editors generated by ArrayEditor() provide text fields (or static text for -the read-only style) for each cell of a two-dimensional Numeric array. Only the +the read-only style) for each cell of a two-dimensional NumPy array. Only the simple and read-only styles are supported by the wxWidgets implementation. You can specify the width of the text fields with the *width* parameter. +This editor is only suitable for small arrays. For editing large +two-dimensional arrays use the ArrayViewEditor instead + .. figure:: images/array_editors.png :alt: 3x3 integer; integer read-only; 4x4 float; float read-only @@ -329,7 +332,7 @@ editor are of the style specified for the compound editor (simple, custom, etc.). The editors shown in Figure 28 are for the following trait, whose value can be an integer between 1 and 6, or any of the letters 'a' through 'f':: - compound_trait = Trait( 1, Range( 1, 6 ), 'a', 'b', 'c', 'd', 'e', 'f') + compound_trait = Trait(1, Range(1, 6), 'a', 'b', 'c', 'd', 'e', 'f') .. figure:: images/compound_editors.png :alt: simple: slider for numbers, drop-list for letters; custom: radio buttons for both @@ -395,23 +398,50 @@ See Also :::::::: ListEditor, TextEditor -DefaultOverride() -````````````````` + +DateEditor() +```````````` :Suitable for: - (any) + Date, List(Date) (custom style only) :Default for: - (none) + Date +:Optional parameters: + *allow_future*, *message*, *months*, *multi_select*, *on_mixed_select*, + *padding*, *shift_to_select*, *selected_style*, *strftime*, *view* + +The DateEditor() displays a Python datetime.date object, usually supplied via a +Date trait. The simple style shows a date spin control, while the custom style +shows one (or potentially more in the wx backend) months in a calendar view. +Dates can be restricted to past-only by setting *allow_future* to False. -The DefaultOverride() is a factory that takes the trait's default editor and -customizes it with the specified parameters. This is useful when a trait defines -a default editor using some of its data, e.g. Range or Enum, and you want to -tweak some of the other parameters without having recreate that data. +The custom style can also be used for the selection of multiple dates as an +ordered list of dates by setting *multi_select* to True. The styling of the +selected dates can be controlled via setting the *selected_style* to a +CellFormat() instance. -For example, the default editor for Range(low=0, high=1500) has -'1500' as the upper label. To change it to 'Max' instead, use:: +For readonly style, the user can set the message to display if the date value +is None, and a date format string for use with strftime. + + +DatetimeEditor() +```````````````` + +:Suitable for: + Datetime +:Default for: + Datetime +:Optional parameters: + *maximum_datetime*, *message*, *minimum_datetime*, *strftime* - View(Item('my_range', editor=DefaultOverride(high_label='Max')) +The DatetimeEditor() displays a Python datetime.datetime object, usually supplied +via a Datetime trait. The simple style shows a datetime spin control, and maximum +and minimum selectable datetimes can be supplied to restrict the range of values. + +For readonly style, the user can set the message to display if the datetime value +is None, and a datetime format string for use with strftime. + +The DatetimeEditor is not yet available for the wxPython backend. DirectoryEditor() @@ -634,6 +664,22 @@ provided. No validation is performed; the user must enter the correct name of an available font. The read-only style is identical except that the text is not editable. +HistoryEditor() +``````````````` + +:Suitable for: + string traits +:Default for: + (none) +:Optional parameters: + *entries* + +HistoryEditor() generates a combo box, which allows the user to either enter a +text string or select a value from a list of previously-entered values. The same +control is used for all editor styles. The *entries* parameter determines how +many entries are preserved in the history list. This type of control is used as +part of the simple style of file editor; see :ref:`fileeditor`. + HTMLEditor() ```````````` @@ -658,9 +704,9 @@ uninterpreted text. .. NOTE:: HTML support is limited in the wxWidgets toolkit. The set of tags supported by the wxWidgets implementation of the HTML editor - is a subset of the HTML 3.2 standard. It does not support style sheets or + is a subset of the HTML standard. It does not support style sheets or complex formatting. Refer to the - `wxWidgets documentation `_ + `wxWidgets documentation `_ for details. If the *format_text* argument is True, then the HTML editor supports basic @@ -692,6 +738,28 @@ The following text produces the same displayed HTML as in Figure 34, when * Two * Three +ImageEditor() +````````````` + +:Suitable for: + (any) +:Default for: + (none) +:Optional parameters: + *image*, *scale*, *preserve_aspect_ratio*, *allow_upscaling*, + *allow_clipping* + +ImageEditor() generates a read-only display of an image. The image to be +displayed is determined by the *image* parameter, or by the value of the trait +attribute being edited, if *image* is not specified. In either case, the value +must be a PyFace ImageResource (pyface.api.ImageResource), or a string +that can be converted to one. If *image* is specified, then the type and value +of the trait attribute being edited are irrelevant and are ignored. + +For the Qt backend *scale*, *preserve_aspect_ratio*, *allow_upscaling*, and +*allow_clipping* control whether the image should be scaled or not, and how +to perform that scaling. + ImageEnumEditor() ````````````````` @@ -836,46 +904,54 @@ Example 16: Instance editor with instance selection from traitsui.api \ import View, Item, InstanceEditor - class Person ( HasStrictTraits ): + class Person(HasStrictTraits): name = Str() age = Int() - phone = Regex( value = '000-0000', - regex = '\d\d\d[-]\d\d\d\d' ) + phone = Regex( + value = '000-0000', + regex = '\d\d\d[-]\d\d\d\d', + ) - traits_view = View( 'name', 'age', 'phone' ) + traits_view = View('name', 'age', 'phone') people = [ - Person( name = 'Dave', age = 39, phone = '555-1212' ), - Person( name = 'Mike', age = 28, phone = '555-3526' ), - Person( name = 'Joe', age = 34, phone = '555-6943' ), - Person( name = 'Tom', age = 22, phone = '555-7586' ), - Person( name = 'Dick', age = 63, phone = '555-3895' ), - Person( name = 'Harry', age = 46, phone = '555-3285' ), - Person( name = 'Sally', age = 43, phone = '555-8797' ), - Person( name = 'Fields', age = 31, phone = '555-3547' ) + Person(name= 'Dave', age=39, phone='555-1212'), + Person(name='Mike', age=28, phone='555-3526'), + Person(name='Joe', age=34, phone='555-6943'), + Person(name='Tom', age=22, phone='555-7586'), + Person(name='Dick', age=63, phone='555-3895'), + Person(name='Harry' age=46, phone='555-3285'), + Person(name='Sally', age=43, phone='555-8797'), + Person(name='Fields', age=31, phone='555-3547') ] - class Team ( HasStrictTraits ): + class Team(HasStrictTraits): name = Str() - captain = Instance( Person ) - roster = List( Person ) - - traits_view = View( Item('name'), - Item('_'), - Item( 'captain', - label='Team Captain', - editor = - InstanceEditor( name = 'roster', - editable = True), - style = 'custom', - ), - buttons = ['OK']) + captain = Instance(Person) + roster = List(Person) + + traits_view = View( + Item('name'), + Item('_'), + Item( + 'captain', + label='Team Captain', + editor = InstanceEditor( + name = 'roster', + editable = True), + style = 'custom', + ), + buttons = ['OK'] + ) if __name__ == '__main__': - Team( name = 'Vultures', - captain = people[0], - roster = people ).configure_traits() + team = Team( + name = 'Vultures', + captain = people[0], + roster = people + ) + team.configure_traits() .. figure:: images/ui_for_ex16.png :alt: Dialog box for a "team", with drop-list selection for "Team Captain" @@ -963,6 +1039,28 @@ user cannot add items interactively through this style of editor. Figure 40: Notebook list editor +LEDEditor() +``````````` + +:Suitable for: + numeric traits +:Default for: + (none) +:Optional parameters: + *alignment, format_str* + +LEDEditor() generates a display that resembles a "digital" display using +light-emitting diodes. All styles of this editor are the same, and are +read-only. + +The *alignment* parameter can be 'left', 'center', or 'right' to indicate how +the value should be aligned within the display. The default is right-alignment. + +.. figure:: images/led_editor.png + :alt: LED-like display of 90452 + + Figure 56: LED Editor with right alignment + ListStrEditor() ``````````````` @@ -1177,6 +1275,23 @@ You can specify a mapping from user input values to other values with the by passing a reference to it in the *evaluate* parameter, or by passing the extended name of a trait that references it in the *evaluate_name* parameter. + +TimeEditor() +```````````` + +:Suitable for: + Time +:Default for: + Time +:Optional parameters: + *minimum_datetime*, *strftime* + +The TimeEditor() displays a Python datetime.time object, usually supplied +via a Time trait. The simple style shows a time spin control. For readonly +style, the user can set the message to display if the time value is None, +and a time format string for use with strftime. + + TitleEditor() ````````````` @@ -1190,6 +1305,7 @@ heading. All styles of the editor are identical. Visually, it is similar to a Heading item, but because it is an editor, you can change the text of the heading by modifying the underlying attribute. + TupleEditor() ````````````` diff --git a/docs/source/traitsui_user_manual/factory_intro.rst b/docs/source/traitsui_user_manual/factory_intro.rst index 0d00889ee..5a561f034 100644 --- a/docs/source/traitsui_user_manual/factory_intro.rst +++ b/docs/source/traitsui_user_manual/factory_intro.rst @@ -105,7 +105,7 @@ Other packages can define their own editor factories for their own traits. For example, enthought.kiva.api.KivaFont uses a KivaFontEditor() and enthought.enable2.traits.api.RGBAColor uses an RGBAColorEditor(). -For most :term:`predefined trait type`\ s (see `Traits User Manual `_), there is +For most :term:`predefined trait type`\ s (see `Traits User Manual `_), there is exactly one predefined trait editor factory suitable for displaying it: the editor factory that is assigned as its default. [15]_ There are exceptions, however; for example, a Str trait defaults to using a TextEditor, but can also @@ -271,7 +271,7 @@ following: For this type of editor, the end user must type in a valid value for the attribute. If the user types an invalid value, the validation method for the -attribute (see `Traits User Manual `_) notifies the user of the error (for +attribute (see `Traits User Manual `_) notifies the user of the error (for example, by shading the background of the text box red). The text representation of an attribute to be edited in a text style editor is diff --git a/docs/source/traitsui_user_manual/front.rst b/docs/source/traitsui_user_manual/front.rst deleted file mode 100644 index ab695f56f..000000000 --- a/docs/source/traitsui_user_manual/front.rst +++ /dev/null @@ -1,42 +0,0 @@ -=============================== -TraitsUI |version| User Manual -=============================== - -:Authors: Lyn Pierce, Janet Swisher, and Enthought Developers -:Version: Document Version 4 -:Copyright: 2005, 2008-2018 Enthought, Inc. All Rights Reserved. - -Redistribution and use of this document in source and derived forms, with or -without modification, are permitted provided that the following conditions are -met: - -* Redistributions of source or derived format (for example, Portable Document - Format or Hypertext Markup Language) must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Neither the name of Enthought, Inc., nor the names of contributors may be used - to endorse or promote products derived from this document without specific - prior written permission. - -THIS DOCUMENT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS DOCUMENT, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -All trademarks and registered trademarks are the property of their respective -owners. - -| Enthought, Inc. -| 515 Congress Avenue -| Suite 2100 -| Austin TX 78701 -| 1.512.536.1057 (voice) -| 1.512.536.1059 (fax) -| http://www.enthought.com -| info@enthought.com diff --git a/docs/source/traitsui_user_manual/handler.rst b/docs/source/traitsui_user_manual/handler.rst index 2d1ee5afc..40d9e0dcd 100644 --- a/docs/source/traitsui_user_manual/handler.rst +++ b/docs/source/traitsui_user_manual/handler.rst @@ -45,21 +45,121 @@ means of the UIInfo object. Whenever TraitsUI creates a window or panel from a View, a UIInfo object is created to act as the Handler's reference to that window and to the objects -whose :term:`trait attribute`\ s are displayed in it. Each entry in the View's -context (see :ref:`the-view-context`) becomes an attribute of the UIInfo -object. [12]_ For example, the UIInfo object created in -:ref:`Example 7 ` +whose :term:`trait attribute`\ s are displayed in it. This object holds a +reference to the UI instance in its **ui** trait, and whether or not +the UI has been initialized in the **initialized** trait. Additionally, +this object is dynamically assigned trait attributes which correspond to: + +- each entry in the View's context (see :ref:`the-view-context`). + +- each item's and group's editor in the view, by id (or name, if no id is + available for an item). + +Where there is conflict between ids, the editors take precedence over context +values, and if two editors have the same name then the last editor with that +name will be referenced. + +For example, the UIInfo object created in :ref:`Example 7 ` has attributes **h1** and **h2** whose values are the objects **house1** and -**house2** respectively. In :ref:`Example 1 ` -through -:ref:`Example 6 `, +**house2** respectively. Additionally it has attributes **address**, +**bedroom**, **pool**, and **price** that reference the editors in the second +group. + +In :ref:`Example 1 ` +through :ref:`Example 6 `, the created UIInfo object has an attribute **object** whose value is the object -**sam**. +**sam**, together with attributes that corrspond to the items in the views, +such as **first_name**, **last_name** and **department**. + Whenever a window event causes a Handler method to be called, TraitsUI passes the corresponding UIInfo object as one of the method arguments. This gives the Handler the information necessary to perform its tasks. +Additionally, traits on objects in the context can be synchronized with traits +on editors via the **sync_to_view**, **sync_from_view** and **sync_with_view** +trait metadata. Note that not every trait on every editor can react to changes: +some values are only used at editor creation time; however all editors support +dynamically changing the **enabled**, **visible** and **invalid** traits. This +feature can sometimes allow developers to avoid having to create a custom Handler +subclass. + +See the :github-demo:`Invalid state handling ` +example which demonstrates how to use this mechanism to control the invalid state +of a dialog based on the value of multiple editors. + +.. _backstage-the-ui-object: + +Backstage: The UI Object +------------------------ + +As opposed to the very dynamic UIInfo object, the UI class provides an object +which ties together the various objects that are involved in a TraitsUI GUI: +the View, the context, the Handler, the underlying toolkit controls and the +shared state of the GUI. It also has some life-cycle and useful utility methods +that can be useful when working from a handler. + +The UI object is returned as the result of a call to edit_traits(), and as noted +in the previous section, is available as the **ui** attribute of the UIInfo object +that is passed to most handler methods. + +.. rubric:: Attributes of UI, by category + +TraitsUI core + view: + View template used to construct the user interface. + handler: + Handler object used for event handling. + context: + Dictionary of objects that the UI is editing. + info: + UIInfo object containing context or editor objects + parent: + The parent UI (if any) of this UI. + +Toolkit + control: + Panel or dialog associated with the user interface. + owner: + Toolkit-specific object that "owns" **control** + +GUI state + id: + The unique ID for this UI for persistence. + title: + Title of the dialog, if any. + icon: + The ImageResource of the dialog icon, if any. + key_bindings: + The KeyBindings object (if any) for this UI. + result: + Result from a modal or wizard dialog. + modified: + Have any modifications been made to UI contents? + updated: + Event when the user interface has changed. + history: + Undo and Redo history. + errors: + The number of currently pending editor error conditions. + Note that changing this must be done very carefully to avoid + permanent error states. + destroyed: + Set to True when the UI has finished being destroyed. + + +.. rubric:: Useful UI methods + ++---------------------------+--------------------------------------------------+ +|Method |Purpose | ++===========================+==================================================+ +|dispose(result, abort) |Disposes of the UI. This can be called to close a| +| |TraitsUI dialog programatically from a handler. | ++---------------------------+--------------------------------------------------+ +|get_editors(name) |Returns a list of all editors matching the name. | ++---------------------------+--------------------------------------------------+ + + .. _assigning-handlers-to-views: Assigning Handlers to Views @@ -488,8 +588,3 @@ created, as in the following code:: .. [11] Except those implemented via the **enabled_when**, **visible_when**, and **defined_when** attributes of Items and Groups. - -.. [12] Other attributes of the UIInfo object include a UI object and any - *trait editors* contained in the window (see - :ref:`introduction-to-trait-editor-factories` and - :ref:`the-predefined-trait-editor-factories`). diff --git a/docs/source/traitsui_user_manual/index.rst b/docs/source/traitsui_user_manual/index.rst index 22f2fb339..b26194255 100644 --- a/docs/source/traitsui_user_manual/index.rst +++ b/docs/source/traitsui_user_manual/index.rst @@ -2,13 +2,20 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. +=============================== TraitsUI |version| User Manual =============================== +:Authors: Lyn Pierce, Janet Swisher, and Enthought Developers +:Version: Document Version 4 +:Copyright: 2005-2020 Enthought, Inc. All Rights Reserved. + +Contents +======== + .. toctree:: :maxdepth: 3 - front.rst intro.rst view.rst custom_view.rst @@ -21,3 +28,41 @@ TraitsUI |version| User Manual tips.rst glossary.rst predefined_traits.rst + + +License +======= + +Redistribution and use of this document in source and derived forms, with or +without modification, are permitted provided that the following conditions are +met: + +* Redistributions of source or derived format (for example, Portable Document + Format or Hypertext Markup Language) must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Neither the name of Enthought, Inc., nor the names of contributors may be used + to endorse or promote products derived from this document without specific + prior written permission. + +THIS DOCUMENT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS DOCUMENT, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +All trademarks and registered trademarks are the property of their respective +owners. + +| Enthought, Inc. +| 200 W Cesar Chavez, Suite 202 +| Austin, TX 78701 +| United States +| 1.512.536.1057 (voice) +| http://www.enthought.com +| info@enthought.com diff --git a/docs/source/traitsui_user_manual/intro.rst b/docs/source/traitsui_user_manual/intro.rst index 5c03a36b0..4da6f4111 100644 --- a/docs/source/traitsui_user_manual/intro.rst +++ b/docs/source/traitsui_user_manual/intro.rst @@ -52,7 +52,7 @@ In the context of Traits, a model consists primarily of one or more subclasses or :term:`instance`\ s of the HasTraits class, whose :term:`trait attribute`\ s (typed attributes as defined in Traits) represent the model data. The specifics of building such a model are outside the scope of this manual; please see the -`Traits User Manual `_ for further information. +`Traits User Manual `_ for further information. .. index:: View; as MVC view @@ -119,8 +119,9 @@ are: .. index:: wxPython toolkit, Qt toolkit, null toolkit -* 'qt4': `PyQt `_, which provides Python - bindings for the `Qt `_ framework version 4. +* 'qt4' or 'qt': `PyQt `_ or + `Qt for Python/PySide2 `_, which provides Python + bindings for the `Qt `_ framework version 4 or 5. * 'wx': `wxPython `_, which provides Python bindings for the `wxWidgets `_ toolkit. * 'null': A do-nothing toolkit, for situations where neither of the other @@ -143,9 +144,6 @@ order of precedence: #. The user can define a value for the ETS_TOOLKIT environment variable. -.. warning:: The default order of toolkits changed in TraitsUI 5.0 to - prefer 'qt4' over 'wx'. - .. _structure-of-this-guide: Structure of this Manual diff --git a/docs/source/tutorials/code_snippets/event_loop_qt.py b/docs/source/tutorials/code_snippets/event_loop_qt.py new file mode 100644 index 000000000..965b81ffe --- /dev/null +++ b/docs/source/tutorials/code_snippets/event_loop_qt.py @@ -0,0 +1,11 @@ +from pyface.qt.QtCore import QApplication + +from traits.api import HasTraits, Int + + +class Counter(HasTraits): + value = Int() + + +Counter().edit_traits() +QApplication.instance().exec_() diff --git a/docs/source/tutorials/code_snippets/event_loop_wx.py b/docs/source/tutorials/code_snippets/event_loop_wx.py new file mode 100644 index 000000000..2c536e2ac --- /dev/null +++ b/docs/source/tutorials/code_snippets/event_loop_wx.py @@ -0,0 +1,11 @@ +import wx + +from traits.api import HasTraits, Int + + +class Counter(HasTraits): + value = Int() + + +Counter().edit_traits() +wx.PySimpleApp().MainLoop() diff --git a/docs/source/tutorials/traits_ui_scientific_app.rst b/docs/source/tutorials/traits_ui_scientific_app.rst index 3dbae92b8..f04341ce7 100644 --- a/docs/source/tutorials/traits_ui_scientific_app.rst +++ b/docs/source/tutorials/traits_ui_scientific_app.rst @@ -21,10 +21,10 @@ python module that provides a great answer to this problem. I have found that I am incredibly productive when creating graphical application using traitsUI. However I had to learn a few new concepts and would like to lay them down together in order to make it easier for others to follow my -footsteps. +footsteps. This document is intended to help a non-programmer to use traits and -traitsUI to write an interactive graphical application. +traitsUI to write an interactive graphical application. The reader is assumed to have some basic python scripting knowledge (see ref [#]_ for a basic introduction). Knowledge of numpy/scipy [#]_ helps understanding the @@ -65,7 +65,7 @@ scientific-computing work-flow, as, during the elaboration of algorithms and data-flow, the objects that are represented in the GUI are likely to change often. -Visual computing, where the programmer creates first a graphical +Visual computing, where the programmer creates first a graphical interface and then writes the callbacks of the graphical objects, gives rise to a slow development cycle, as the work-flow is centered on the GUI, and not on the code. @@ -134,7 +134,7 @@ A point object could be implemented in python with: x = 0. y = 0. z = 0. - + def rotate_z(self, theta): """ rotate the point around the Z axis """ xtemp = cos(theta) * self.x + sin(theta) * self.y @@ -166,7 +166,7 @@ internal details of their procedures. As long as the object has a structures that know how to modify themselves. Part of the point of object-oriented programming is that the object is responsible for modifying itself through its methods. The object therefore takes care - of its internal logic and the consistency between its attributes. + of its internal logic and the consistency between its attributes. In python, dictionaries make great structures and are more suited for such a use than objects. @@ -298,7 +298,7 @@ like (see the TraitsUI manual): camera = Instance(Camera) display = Instance(TextDisplay) - view = View( + view = View( Item('camera', style='custom', show_label=False, ), Item('display', style='custom', show_label=False, ), ) @@ -357,49 +357,55 @@ execution of his program. An event loop allows the programmer to develop an application in which each user action triggers an event, by stacking the user created events on a queue, and processing them in the order in which the appeared. - + A complex GUI is made of a large numbers of graphical elements, called widgets (e.g., text boxes, check boxes, buttons, menus). Each of these widgets has specific behaviors associated with user interaction (modifying the content of a text box, clicking on a button, opening a menu). It is natural to use objects to represent the widgets, with their behavior being set in the object's methods. - + Dialogs populated with widgets are automatically created by `traitsUI` in the *configure_traits()* call. `traitsUI` allow the developer to not worry about widgets, but to deal only with objects and their attributes. This is a fabulous gain as the widgets no longer appear in the code, but -only the attributes they are associated to. +only the attributes they are associated to. A *HasTraits* object has an *edit_traits()* method that creates a graphical panel to edit its attributes. This method creates and returns the panel, but does not start its event loop. The panel is not yet "alive", unlike with the *configure_traits()* method. Traits uses the -wxWidget toolkit by default to create its widget. They can be turned live -and displayed by starting a wx application, and its main loop (ie event -loop in wx speech). +Qt toolkit by default to create its widget. They can be turned live +and displayed by starting a Qt application, and its main loop (ie event +loop in Qt speech). - `code snippet #3 <../_static/event_loop.py>`_ + `code snippet #3 <../_static/event_loop_qt.py>`_ .. code-block:: python - from traits.api import * - import wx + from pyface.qt.QtCore import QApplication + + from traits.api import HasTraits, Int + class Counter(HasTraits): - value = Int() + value = Int() + Counter().edit_traits() - wx.App().MainLoop() + QApplication.instance().exec_() +There is a `similar example for wxPython <../_static/event_loop_wx.py>`_ +and a `toolkit-independent example that uses Pyface <../_static/event_loop.py>`_ +as well. The *Counter().edit_traits()* line creates a counter object and its representation, a dialog with one integer represented. However it does -not display it until a wx application is created, and its main loop is +not display it until a Qt application is created, and its main loop is started. -Usually it is not necessary to create the wx application yourself, and to +Usually it is not necessary to create the Qt application yourself, and to start its main loop, traits will do all this for you when the *.configure_traits()* method is called. @@ -500,7 +506,7 @@ A standard python program executes in a sequential way. Consider the following code snippet : .. code-block:: python - + do_a() do_b() do_c() @@ -554,7 +560,7 @@ The above code yields the following output:: Main thread done MyThread done - + Getting threads and the GUI event loop to play nice ``````````````````````````````````````````````````` @@ -572,7 +578,7 @@ thread will lead to race conditions, and unpredictable crash: suppose the GUI was repainting itself (due to a window move, for instance) when you modify it. -In a wxPython application, if you start a thread, GUI event will still be +In an application, if you start a thread, GUI event will still be processed by the GUI event loop. To avoid collisions between your thread and the event loop, the proper way of modifying a GUI object is to insert the modifications in the event loop, using the *GUI.invoke_later()* call. @@ -709,8 +715,8 @@ powerful tool for plotting we have to get our hands a bit dirty and create our own traits editor. This involves some `wxPython` coding, as we need to translate a -`wxPython` object to a traits editor by providing the corresponding API -(i.e. the standard way of building a `traits` editor), so that the `traits` +`wxPython` object to a traits editor by providing the corresponding API +(i.e. the standard way of building a `traits` editor), so that the `traits` framework will know how to create the editor. Traits editor are created by an editor factory that instantiates an @@ -745,7 +751,7 @@ displaying and positioning the editor. def init(self, parent): self.control = self._create_canvas(parent) self.set_tooltip() - + def update_editor(self): pass @@ -821,7 +827,7 @@ Toronto. The reason I am providing this code is to give an example to study of how a full-blown application can be built. This code can be found in the -`tutorial's zip file `_ +`tutorial's zip file `_ (it is the file `application.py`). * The camera will be built as an object. Its real attributes (exposure @@ -845,7 +851,7 @@ The MPLFigureEditor is imported from the last example. from traits.api import * from traitsui.api import View, Item, Group, HSplit, Handler from traitsui.menu import NoButtons - from mpl_figure_editor import MPLFigureEditor + from mpl_figure_editor import MPLFigureEditor from matplotlib.figure import Figure from scipy import * import wx @@ -875,7 +881,7 @@ via traitsUI. view = View( Item('width', style='readonly'), Item('x', style='readonly'), - Item('y', style='readonly'), + Item('y', style='readonly'), ) The camera object also is a real object, and not only a data structure: @@ -1080,7 +1086,7 @@ produces noisy gaussian images, and the processing code estimates the parameters of the gaussian. Here are screenshots of the three different tabs of the application: - + .. image:: images/application1.png .. image:: images/application2.png diff --git a/traitsui/context_value.py b/traitsui/context_value.py index 222f9264b..73589ad41 100644 --- a/traitsui/context_value.py +++ b/traitsui/context_value.py @@ -69,7 +69,7 @@ class ContextValue(HasStrictTraits): """ Defines the name of a context value that can be bound to an editor Resolution of the name follows the same rules as for context values in - :class:`.Item`s: if there is no dot in it then it is treated as an + Item objects: if there is no dot in it then it is treated as an attribute of the 'object' context value, other wise the first part specifies the object in the context and the rest are dotted attribute look-ups. diff --git a/traitsui/editors/date_editor.py b/traitsui/editors/date_editor.py index 7ae0ac650..459f8f8c2 100644 --- a/traitsui/editors/date_editor.py +++ b/traitsui/editors/date_editor.py @@ -25,23 +25,33 @@ class CellFormat(object): - """ Encapsulates some common visual attributes to set on the cells of a + """ Styling attributes for calendar widget cells. + + Encapsulates some common visual attributes to set on the cells of a calendar widget. All attributes default to None, which means that they will not override the existing values of the calendar widget. + + The color attributes should be strings representing color names, + from the list: red, green, blue, cyan, magenta, yellow, gray, white, + darkRed, darkGreen, darkBlue, darkCyan, darkmagenta, darkYellow, + darkGray, black, lightGray. + + Alternatively, they can be a tuple of (R,G,B) values from 0-255. """ + #: Whether to display in an italic style. italics = None + + #: Whether to use a bold weight. bold = None + + #: Whether to underline the text. underline = None - #: The color attributes should be strings representing color names, - #: from the list: - #: red, green, blue, cyan, magenta, yellow, gray, white, - #: darkRed, darkGreen, darkBlue, darkCyan, darkmagenta, darkYellow, - #: darkGray, black, lightGray - #: - #: Alternatively, they can be a tuple of (R,G,B) values from 0-255. + #: The background color. bgcolor = None + + #: The text color. fgcolor = None def __init__(self, **args): @@ -82,17 +92,16 @@ class DateEditor(EditorFactory): #: When a user multi-selects entries and some of those entries are already #: selected and some are not, what should be the behavior for the seletion? - #: Options:: #: - #: 'toggle' -- Toggle each day to the opposite of the current state. - #: 'on' -- Always turn them on. - #: 'off' -- Always turn them off. - #: 'max_change' -- Change all to same state, with most days changing. - #: For example 1 selected and 9 not, then they would - #: all get selected. - #: 'min_change' -- Change all to same state, with min days changing. - #: For example 1 selected and 9 not, then they would - #: all get unselected. + #: Options: + #: + #: - 'toggle': Toggle each day to the opposite of the current state. + #: - 'on': Always turn them on. + #: - 'off': Always turn them off. + #: - 'max_change': Change all to same state, with most days changing. + #: For example 1 selected and 9 not, then they would all get selected. + #: - 'min_change': Change all to same state, with min days changing. + #: For example 1 selected and 9 not, then they would all get unselected. on_mixed_select = Enum("toggle", "on", "off", "max_change", "min_change") #: How much space to put between the individual months. diff --git a/traitsui/editors/time_editor.py b/traitsui/editors/time_editor.py index 8381fdcfe..971ac8319 100644 --- a/traitsui/editors/time_editor.py +++ b/traitsui/editors/time_editor.py @@ -15,7 +15,7 @@ # # ------------------------------------------------------------------------------ -""" A Traits UI editor that wraps a WX timer control. +""" A Traits UI editor that wraps a timer control. """ @@ -25,7 +25,7 @@ class TimeEditor(EditorFactory): - """ Editor factory for time editors. Generates _TimeEditor()s. + """ Editor factory for time editors. """ # ------------------------------------------------------------------------- diff --git a/traitsui/table_column.py b/traitsui/table_column.py index e98dc23ad..febeb5a65 100644 --- a/traitsui/table_column.py +++ b/traitsui/table_column.py @@ -144,10 +144,10 @@ class TableColumn(HasPrivateTraits): #: The resize mode for this column. This takes precedence over other settings #: (like **width**, above). - #: "interactive": column can be resized by users or programmatically - #: "fixed": users cannot resize the column, but it can be set programmatically - #: "stretch": the column will be resized to fill the available space - #: "resize_to_contents": column will be sized to fit the contents, but then cannot be resized + #: - "interactive": column can be resized by users or programmatically + #: - "fixed": users cannot resize the column, but it can be set programmatically + #: - "stretch": the column will be resized to fill the available space + #: - "resize_to_contents": column will be sized to fit the contents, but then cannot be resized resize_mode = Enum("interactive", "fixed", "stretch", "resize_to_contents") #: The view (if any) to display when clicking a non-editable cell: diff --git a/traitsui/toolkit_traits.py b/traitsui/toolkit_traits.py index 27f73c219..f2b0517d8 100644 --- a/traitsui/toolkit_traits.py +++ b/traitsui/toolkit_traits.py @@ -1,10 +1,10 @@ -# Copyright (c) 2005-20, Enthought, Inc. -# All rights reserved. +# Copyright (c) 2005-20, Enthought, Inc. +# All rights reserved. # -# This software is provided without warranty under the terms of the BSD -# license included in enthought/LICENSE.txt and may be redistributed only -# under the conditions described in the aforementioned license. The license -# is also available online at http://www.enthought.com/licenses/BSD.txt +# This software is provided without warranty under the terms of the BSD +# license included in enthought/LICENSE.txt and may be redistributed only +# under the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt # XXX eventually should replace with traits.api @@ -14,60 +14,79 @@ def ColorTrait(*args, **traits): - """ Returns a trait whose value must be a GUI toolkit-specific color. + """ Returns a trait whose value is a GUI toolkit-specific color. - Description - ----------- - For wxPython, the returned trait accepts any of the following values: + A number of different values are accepted for setting the value, including: - * A wx.Colour instance - * A wx.ColourPtr instance - * an integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red - value, *GG* is the green value, and *BB* is the blue value + * tuples of the form (r, g, b) and (r, g, b, a) + * strings which match standard color names + * strings of the form "(r, g, b)" and "(r, g, b, a)" + * integers whose hex value is of the form 0xRRGGBB + * toolkit-specific color classes - Default Value - ------------- - For wxPython, 0xffffff (that is, white) + Tuple values are expected to be in the range 0 to 255. + + Exact behaviour (eg. precisely what values are accepted, and what the + "standard" color names are) is toolkit-dependent. + + The default value is white. The default editor is a ColorEditor. + + Parameters + ---------- + default: color + The default color for the trait. + allow_none: bool + Whether to allow None as a value. + **metadata + Trait metadata to be passed through. """ return toolkit().color_trait(*args, **traits) def RGBColorTrait(*args, **traits): - """ Returns a trait whose value must be a GUI toolkit-specific RGB-based - color. - - Description - ----------- - For wxPython, the returned trait accepts any of the following values: - - * A tuple of the form (*r*, *g*, *b*), in which *r*, *g*, and *b* represent - red, green, and blue values, respectively, and are floats in the range - from 0.0 to 1.0 - * An integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red - value, *GG* is the green value, and *BB* is the blue value - - Default Value - ------------- - For wxPython, (1.0, 1.0, 1.0) (that is, white) + """ Returns a trait whose value is a RGB tuple with values from 0 to 1. + + A number of different values are accepted for setting the value, including: + + * tuples of the form (r, g, b) with values from 0.0 to 1.0 + * strings which match standard color names + * integers whose hex value is of the form 0xRRGGBB + + The default value is (1.0, 1.0, 1.0). The default editor is a + RGBColorEditor. + + Parameters + ---------- + **metadata + Trait metadata to be passed through. """ return toolkit().rgb_color_trait(*args, **traits) def FontTrait(*args, **traits): - """ Returns a trait whose value must be a GUI toolkit-specific font. + """ Returns a trait whose value is a GUI toolkit-specific font. + + This trait accepts either a toolkit-specific font object, or a string + containing a font description. The string description can contain: + + * a font name or family. The following generic names are understood: + "default", "decorative", "roman", "script", "swiss", and "modern". + * a size, in points. + * a style, which is one of: "slant" or "italic" + * a weight, which is one of: "light" or "bold" + * whether the font is underlined, indicated by the inclusion of + "underlined". - Description - ----------- - For wxPython, the returned trait accepts any of the following: + Where values aren't supplied, the application defaults will be used + instead. - * a wx.Font instance - * a wx.FontPtr instance - * a string describing the font, including one or more of the font family, - size, weight, style, and typeface name. + The default value is the application default font, which is toolkit + and platform dependent. The default editor is FontEditor. - Default Value - ------------- - For wxPython, 'Arial 10' + Parameters + ---------- + **metadata + Trait metadata to be passed through. """ return toolkit().font_trait(*args, **traits)