Welcome to Editobj3’s documentation!

Editobj3 is an automatic dialog box generator for Python objects. It supports several backends; currenlty GTK and HTML are supported. The HTML backend is based on W2UI, and can be used either in local single user mode, or in distributed multiple users mode.

Editobj3 dialog boxes are composed of an attribute list, a luxurious good-looking but useless icon and title bar, and a tree view (if the edited object is part of a tree-like structure). Editobj3 includes an advanced introspection module that usually guesses how to edit any object; it can also be customized for a given class of object through the editobj3.introsp module. Editobj3 also supports the simultaneous edition of a group of objects, as if they were a single object.

Additional helper modules are included:

  • editobj3.observe: Observation framework
  • editobj3.undoredo: Multiple undo/redo framework
  • editobj3.http_ws_server: HTTP server with WebSocket support, with an interface similar to Python’s http.server module

Editobj3 has been created by Jean-Baptiste Lamy. It is available under the GNU LGPL licence.

In case of trouble, please contact Jean-Baptiste Lamy <jibalamy @ free . fr>

_images/editobj3_gtk.png

Screenshot of an Editobj3 dialog box with GTK backend

_images/editobj3_html.png

Screenshot of an Editobj3 dialog box with HTML backend

Automatic dialog box generation

Editobj3 – An automatic dialog box generator

Editobj is able to generate a dialog box for editing almost any Python object. The dialog box is composed of an attribute list, a luxurious good-looking but useless icon and title bar, and a tree view (if the edited object is part of a tree-like structure). The default dialog box can be customized and adapted for a given class of object through the editobj3.introsp module.

Editobj3 has multiple GUI support; it currently supports Qt, Gtk and HTML.

Editobj3 was inspired by Java’s “Bean Editor”, however the intial concept have been extended by adding icons, tree views, undo/redo, translation support, automatic update on object changes, and support for editing several objects as if there was only one (see editobj3.introsp.ObjectPack).

The editobj3 package contains the following modules:

  • editobj3.introsp: High level, highly customizable introspection (go there for customizing Editobj3 dialog boxes)
  • editobj3.observe: Observation framework
  • editobj3.undoredo: Multiple undo/redo support
  • editobj3.editor: The editor dialog boxes and related widgets
  • editobj3.field: The set of basic fields for attribute panes

The following global variables can be changed:

  • editobj3.GUI: the default GUI system (default is Qt if available, else Gtk, else HTML)
  • editobj3.TRANSLATOR: the translator function used for translating dialog boxes.

It can be set to a translator function (such as the ones from the gettext module).

The edit() function in this module is an easy way to quickly edit an object. More complex edition can be done using the widget available in editobj3.editor.

editobj3.introsp – Introspection framework

class editobj3.introsp.ClassDescr(klass, inherited_classes)

A class description. It describes the attributes of the class and their types, the associated icon,… Editobj3 is able to automatically guess the attributes and their types, but you can overide the guessed value by calling various methods of the class description.

Warning

You should not create ClassDescr, but rather call description().

def_attr(attr, field_class = "auto", unit = "auto", priority = "auto", inverse_attr = "auto", optional = "auto", get_method = "auto", set_method = "auto", addable_values = "auto", add_method = "auto", remove_method = "auto", reorder_method = "auto", has_item_method = "auto", label = None)

This method is similar to editobj3.introsp.def_attr(), but it is restricted to the class described by this class description (including subclasses).

set_constructor(constructor)

Set the constructor for this class. By default, EditObj 3 creates new instances by calling the class with a single argument: the parent objet. If your class’s __init__ does not work like that, you can either set a Constructor, or create a FormConstructor subclass if you need to ask some information to the user prior to create the instance.

Example of Constructor if the class’s __init__ does not expect any argument:

>>> descr.set_constructor(introsp.Constructor(lambda klass, parent: klass()))

Example of a FormConstructor asking the user for a “name” argument:

>>> class MyFormConstructor(introsp.FormConstructor):
>>>   def __init__(self):
>>>     self.name = "default name"
>>> descr.set_constructor(MyFormConstructor)
Parameters:constructor – a Constructor object, a FormConstructor subclass, or None for using the class itself as a constructor.
set_details(details)

Set the details for this class. If no details are provided, an empty string is used.

Parameters:details – either a string (the details) or a callable (taking one argument, the object, and returning the details).
set_icon_filename(icon_filename)

Set the icon filename for this class. If no icon is provided, a Python icon is used.

Parameters:icon_filename – either a string (the icon filename) or a callable (taking one argument, the object, and returning the icon filename).
set_label(label)

Set the label for this class. If no label is provided, the str() function is used.

Parameters:label – either a string (the label) or a callable (taking one argument, the object, and returning the label).
editobj3.introsp.def_attr(attr, field_class = "auto", unit = "auto", priority = "auto", inverse_attr = "auto", optional = "auto", get_method = "auto", set_method = "auto", addable_values = "auto", add_method = "auto", remove_method = "auto", reorder_method = "auto", has_item_method = "auto", label = None)

Defines an attribute.

Parameters:
  • attr – the name of the attribute, or “__list__”.
  • field_class – the class of field used to edit the attribute (see editobj3.field), or None to hide the attribute.
  • unit – the unit displayed on the right of the editing field (default to no unit).
  • priority – the priority value, used for ordering the attributes in the attribute pane (default: display the attributes in the order they have been def_attr’ed); use None if you don’t want to change the priority.
  • inverse_attr – the name of the inverse attribute (e.g. ‘parent’ attribute is tipically the inverse of ‘children’); inverse attributes are automatically hidden in the tree view (default: not inverse attribute).
  • optional – the attribute may not be defined for all instances of the class (default: True, except for property and get/set attributes).
  • get_method – the method for getting the value of the attribute.
  • set_method – the method for setting the value of the attribute.
  • addable_values – the list of possible values to add (to a list or set attribute), or the value that the attribute can take for (for non-list object attribute). Can also be a callable that returns the list of addable values for the given object (given in argument). Use NewInstanceOf for allowing the addition of fresh new instances of a given class.
  • add_method – the method for adding items to the attribute’s value (only meaningful for list or set attribute) Notice that ADD_METHOD also accept insert-like method (this should be preferred for ordered values).
  • remove_remove – the method for removing items from the attribute’s value.
  • reorder_method – the method for reordering items in the attribute’s value.
  • has_item_method – the method for testing the presence of items in the attribute’s value.
  • label – the label for displaying the attribute (default to the attribute name).

All *_method parameters can be a method name, a callable, or None (to disable the corresponding functionality).

Except for the two first parameters, all parameters to def_attr() must be given by name, for example:

>>> introsp.def_attr("hit_points", field.IntField, unit = "HP")
>>> introsp.def_attr("items", field.ObjectListField,
                     addable_values = [NewInstanceOf(Item)],
                     add_method = "add_item",
                     )
editobj3.introsp.description(klass)

Returns the class description for the given class. The class description is created if not already existing.

Parameters:Klass – the class.
Returns:a class description (ClassDescr).
editobj3.introsp.description_for_class(klass)

Returns the class description for the given class. The class description is created if not already existing.

Parameters:Klass – the class.
Returns:a class description (ClassDescr).
editobj3.introsp.description_for_object(o)

Returns the class description for the given object. The class description is created if not already existing.

Parameters:o – the object.
Returns:a class description (ClassDescr).
editobj3.introsp.description_for_type(type)

Returns the description for the given type. The description is created if not already existing.

Parameters:type – the type.
Returns:a class description (ClassDescr).
editobj3.introsp.print_info(o)

Prints the information available from introsp for the given object.

Parameters:o – the object.

editobj3.editor – The main widget for object edition

editobj3.field: Fields for attribute pane

This module provides the field used by Editobj3 for editing the various attributes in the attribute panes. For assigning a given class of field to an attribute, see editobj3.instrosp

The following field classes are the simplest; they do not allow editon:

class editobj3.field.HiddenField(gui, master, o, attribute, undo_stack)

A field that is not displayed. Use it whenever you want to hide an attribute.

class editobj3.field.LabelField(gui, master, o, attribute, undo_stack)

A field that displays the attribute’s value, without allowing the user to modify the value.

class editobj3.field.ProgressBarField(gui, master, o, attribute, undo_stack)

A field for showing completion of a task, expressed by a float attribute between 0.0 and 1.0. Displays as a progressbar.

The following field classes allow the edition of the basic data types:

class editobj3.field.BoolField(gui, master, o, attribute, undo_stack)

A field for editing a boolean attribute. Displays as a checkbox.

class editobj3.field.IntField(gui, master, o, attribute, undo_stack)

A field for editing an int. Displays as a one-line text field for entering an integer.

class editobj3.field.FloatField(gui, master, o, attribute, undo_stack)

A field for editing a float. Displays as a one-line text field for entering a float number.

class editobj3.field.StringField(gui, master, o, attribute, undo_stack)

A field for editing a string (without breakline). Displays as a one-line text field for entering a string.

class editobj3.field.TextField(gui, master, o, attribute, undo_stack)

A field for editing a string (with breakline). Displays as a multi-line text field for entering a string.

editobj3.field.RangeField(min, max, incr=0)

A field for editing an integer or float attribute in a given range. Displays as a slider. The choice of integer or float depends on the value passed to the function.

Parameters:
  • min – minimum allowed value.
  • max – maximum allowed value.
  • incr – default increments.
editobj3.field.EnumField(choices, value_2_enum=None, enum_2_value=None, long_list=None, translate=True, allow_multiple_selection=False)

A field for editing attributes that can take a fixed set of possible values. Displays as a drop-down box or a list.

Parameters:
  • choices – the list of possible choices. Can be a list of value, a dictionary, or a callable that takes one parameter (the object edited) and returns the allowed values.
  • value_2_enum – an optional function that maps choice value to their enum label, such as: map_value_to_enum_for_object(object, value) -> enum
  • enum_2_value – an optional function that maps enum label to the corresponding value, such as: map_enum_to_value_for_object(object, enum) -> value
  • long_list – if True, displays as a list. If False, displays as a drop-down box. If None, Editobj3 choose automatically depending on the number of items.
  • translate – if True, the enum value are translated using editobj3.TRANSLATOR().

The following field classes are specialized string editors:

class editobj3.field.PasswordField(gui, master, o, attribute, undo_stack)

A field for entering a password. Displays as a one-line text field whoose value is hidden value.

class editobj3.field.FilenameField(gui, master, o, attribute, undo_stack, field_class=None, button_text=None, on_button=None)

A field for editing a filename. Displays as a one-line text field with a button for opening a file.

class editobj3.field.DirnameField(gui, master, o, attribute, undo_stack, field_class=None, button_text=None, on_button=None)

A field for editing a directory name. Displays as a one-line text field with a button for choosing a directory.

class editobj3.field.URLField(gui, master, o, attribute, undo_stack, field_class=None, button_text=None, on_button=None)

A field for editing an URL. Displays as a one-line text field with a button for opening the URL in a web browser.

The following field classes allow the edition of lists of various data types:

class editobj3.field.IntListField(gui, master, o, attribute, undo_stack)

A field for editing a list of integers. Displays as a multi-line text field (one item per line).

class editobj3.field.FloatListField(gui, master, o, attribute, undo_stack)

A field for editing a list of float numbers. Displays as a multi-line text field (one item per line).

class editobj3.field.StringListField(gui, master, o, attribute, undo_stack)

A field for editing a list of strings (without breakline). Displays as a multi-line text field (one item per line).

editobj3.field.EnumListField(choices, value_2_enum=None, enum_2_value=None, translate=True)

A field for editing a set or a list that is a subset of a fixed set of possible values. Displays as a list. This field is similar to EnumField but allows multiple selection.

Parameters:
  • choices – the list of possible choices. Can be a list of value, a dictionary, or a callable that takes one parameter (the object edited) and returns the allowed values. Hint: use an ordered dict if you want to preserve order.
  • value_2_enum – an optional function that maps choice value to their enum label, such as: map_value_to_enum_for_object(object, value) -> enum
  • enum_2_value – an optional function that maps enum label to the corresponding value, such as: map_enum_to_value_for_object(object, enum) -> value
  • translate – if True, the enum value are translated using editobj3.TRANSLATOR().

The following field classes allow the edition of object attributes and lists of objects:

class editobj3.field.ObjectAttributeField(gui, master, o, attribute, undo_stack)

A field for editing an object. Displays as an attribute panel embedded inside the main attribute panel. The attribute is not displayed in the tree.

class editobj3.field.ObjectSelectorField(gui, master, o, attribute, undo_stack)

A field for editing an object attribute. Display as a drop-down box for choosing the object in a list and a button for editing the object. The list of possible values is determined using editobj3.introsp and more specifically the addable_values parameter. The attribute is not displayed in the tree.

class editobj3.field.ObjectListField(gui, master, o, attribute, undo_stack)

A field for editing a list of objects. Display as a list with button for adding, moving and removing the objects. The list of possible values is determined using editobj3.introsp and more specifically the addable_values parameter. The attribute is not displayed in the tree.

class editobj3.field.HierarchyOrObjectAttributeField(gui, master, o, attribute, undo_stack)

Similar to ObjectAttributeField, but displays the attribute in the hierarchical tree if available.

class editobj3.field.HierarchyOrObjectSelectorField(gui, master, o, attribute, undo_stack)

Similar to ObjectSelectorField, but displays the attribute in the hierarchical tree if available.

class editobj3.field.HierarchyOrObjectListField(gui, master, o, attribute, undo_stack)

Similar to ObjectListField, but displays the attribute in the hierarchical tree if available.

class editobj3.field.HierarchyAndObjectAttributeField

Similar to ObjectAttributeField, but displays the attribute both in the hierarchical tree and in the attribute pane.

class editobj3.field.HierarchyAndObjectSelectorField

Similar to ObjectSelectorField, but displays the attribute both in the hierarchical tree and in the attribute pane.

class editobj3.field.HierarchyAndObjectListField

Similar to ObjectListField, but displays the attribute both in the hierarchical tree and in the attribute pane.

Extending Editobj3 with additional Field or Editor widgets

Backends specificities

GTK backend

HTML backend

Helper modules

editobj3.observe: Observation framework

The observe module can register listeners for any Python object. When the object is modified, the listeners will be (asynchronously) called. The following objects can be observed: Python instance, lists and dictionaries. A listener is a function of the form:

def my_listener(obj, type, new, old):
  ...

where obj is the modified object, type is the type of the modification, and old and new are the old and new values. Type can be:

  • object (the Python root class): one or more attributes have changed on obj. old and new are the old and new attribute dictionary of obj (this dictionary includes attributes in obj.__dict__, but also Python’s property and C-level getset). If you want to know which attribute has changed, use dictdiff on new and old (see the diffdict function docstring).
  • list : one or more addition / deletion have occured on obj (which is a list). new and old are the new and old list content of obj.
  • dict : one or more assignment / deletion have occured on obj (which is a dictionary). new and old are the new and old dictionary values.
  • “__class__” : the class of obj has changed. new and old are the new and old classes.

The scan() function checks all observed objects and calls the corresponding listeners.

Quick example:
>>> from editobj3.observe import *
>>> class C: pass
...
>>> c = C()
>>> def listener(obj, type, new, old):
...   if type is object:
...     for (attr, newvalue, oldvalue) in diffdict(new, old):
...       print("c.%s was %s, is now %s" % (attr, oldvalue, newvalue))
>>> observe(c, listener)
>>> c.x = 1
>>> scan()
c.x was None, is now 1
editobj3.observe.observe(o, listener)

Registers a listener for the given object. When o will be changed, the listener will be called (asynchronously). See the module docstrings for more info about what arguments receives a listener.

Parameters:
  • o – the object to observe.
  • listener (callable) – the listener.
editobj3.observe.isobserved(o, listener=None)

Returns true if the given object is observed by the given listener. If listener is None, returns the list of active listeners for o.

Parameters:
  • o – the object.
  • listener – the listener, or None.
Returns:

True, False or list.

editobj3.observe.unobserve(o, listener=None)

Unregisters the given listener for o. If listener is not listening o, nothing is done. If listener is None, unregisters all listeners on o.

Parameters:
  • o – the object.
  • listener – the listener, or None.
editobj3.observe.observe_tree(o, listener, find_children=<function find_all_children>)

Observes o with listener, as well as any item recursively in o (if o is a list, a dict, or have attributes). Items added to or removed from o or one of its items are automatically observed or unobserved. Although called “observe_tree”, it works with any nested structure of lists and dicts, including cyclic ones.

You must use unobserve_tree() to remove the listener.

Parameters:
  • o – the object to observe.
  • listener (callable) – the listener.
  • find_children – optional function to call for listing the children of o.
editobj3.observe.unobserve_tree(o, listener, find_children=<function find_all_children>, already=None)

Unregisters the given tree listener for o.

Parameters:
  • o – the object to observe.
  • listener – the listener, or None for unregistering all listeners.
  • find_children – optional function to call for listing the children of o.
editobj3.observe.scan()

Checks for changes in all listened objects, and calls the corresponding listeners if needed.

editobj3.observe.diffdict(new, old, inexistent_value=None)

Returns the differences between two dictionaries. In case of addition or deletion, old or new values are set to inexistent_value.

Parameters:
  • new – first dictionary to compare.
  • old – second dictionary to compare.
  • inexistent_value – value used as old or new value for deletion or addition, defaults to None.
Returns:

a list of the differences between the two dictionaries, like: [(key, new_value, old_value),…]

editobj3.undoredo: Multiple undo/redo framework

This module contains a multiple undo/redo framework. It is used by Editobj3 dialog boxes, and it automatically call editobj3.observe.scan() when doing or undoing an operation.

editobj3.undoredo.stack the default undo/redo stack.
class editobj3.undoredo.Stack(limit=20)

An undo/redo stack.

Parameters:limit – the maximum number of undo/redo, defaults to 20.
can_redo()

Returns True if it is possible to redo an operation.

can_undo()

Returns True if it is possible to undo an operation.

clear()

Clears all undo/redo operations.

do_operation(operation)

Does the operation. Can be overriden, e.g. to save data after the changes performed by the operation.

Parameters:operation (Operation) – the operation.
merge_last_operations(name='', nb=2)

Merges the NB last operations. They will now be undone / redone as a single operation, with the given NAME.

redo()

Redoes the last operation available.

undo()

Undoes the last operation available.

class editobj3.undoredo.UndoableOperation(do_func, undo_func, name = "", stack = undoredo.stack)

An operation that can be undone.

Parameters:
  • do_func – a callable that do the operation when called.
  • undo_func – a callable that undo the operation when called.
  • name – the name of the operation.
  • stack – the undo/redo stack to add the operation to, defaults to undoredo.stack.

Indices and tables