Event reference

Component

class flexx.event.Component(*init_args, **property_values)

The base component class.

Components have attributes to represent static values, properties to represent state, actions that can mutate properties, and reactions that react to events such as property changes.

Initial values of properties can be provided by passing them as keyword arguments.

Subclasses can use Property (or one of its subclasses) to define properties, and the action, reaction, and emitter decorators to create actions, reactions. and emitters, respectively.

class MyComponent(event.Component):

    foo = event.FloatProp(7, settable=True)
    spam = event.Attribute()

    @event.action
    def inrease_foo(self):
        self._mutate_foo(self.foo + 1)

    @event.reaction('foo')
    def on_foo(self, *events):
        print('foo was set to', self.foo)

    @event.reaction('bar')
    def on_bar(self, *events):
        for ev in events:
            print('bar event was emitted')

    @event.emitter
    def bar(self, v):
        return dict(value=v)  # the event to emit
_comp_apply_property_values(values)

Apply given property values, prefer using a setter, mutate otherwise.

_comp_init_property_values(property_values)

Initialize property values, combining given kwargs (in order) and default values.

_comp_init_reactions()

Create our own reactions. These will immediately connect.

_comp_stop_capturing_events()

Stop capturing events and flush the captured events. This gets scheduled to be called asap after initialization. But components created in our init() go first.

_mutate(prop_name, value, mutation='set', index=-1)

Mutate a property. Can only be called from an action.

Each Component class will also have an auto-generated mutator function for each property: e.g. property foo can be mutated with c._mutate('foo', ..) or c._mutate_foo(..).

Parameters:
  • prop_name (str) – the name of the property being mutated.
  • value – the new value, or the partial value for partial mutations.
  • mutation (str) – the kind of mutation to apply. Default is ‘set’. Partial mutations to list-like properties can be applied by using ‘insert’, ‘remove’, or ‘replace’. If other than ‘set’, index must be specified, and >= 0. If ‘remove’, then value must be an int specifying the number of items to remove.
  • index – the index at which to insert, remove or replace items. Must be an int for list properties.

The ‘replace’ mutation also supports multidensional (numpy) arrays. In this case value can be an ndarray to patch the data with, and index a tuple of elements.

_registered_reactions_hook()

This method is called when the reactions change, can be overloaded in subclasses. The original method returns a list of event types for which there is at least one registered reaction. Overloaded methods should return this list too.

disconnect(type, reaction=None)

Disconnect reactions.

Parameters:
  • type (str) – the type for which to disconnect any reactions. Can include the label to only disconnect reactions that were registered with that label.
  • reaction (optional) – the reaction object to disconnect. If given, only this reaction is removed.
dispose()

Use this to dispose of the object to prevent memory leaks. Make all subscribed reactions forget about this object, clear all references to subscribed reactions, and disconnect all reactions defined on this object.

emit(type, info=None)

Generate a new event and dispatch to all event reactions.

Parameters:
  • type (str) – the type of the event. Should not include a label.
  • info (dict) – Optional. Additional information to attach to the event object. Note that the actual event is a Dict object that allows its elements to be accesses as attributes.
get_event_handlers(type)

Get a list of reactions for the given event type. The order is the order in which events are handled: alphabetically by label. Intended mostly for debugging purposes.

Parameters:type (str) – the type of event to get reactions for. Should not include a label.
get_event_types()

Get the known event types for this component. Returns a list of event type names, for which there is a property/emitter or for which any reactions are registered. Sorted alphabetically. Intended mostly for debugging purposes.

id

attribute – The string by which this component is identified.

init()

Initializer method. This method can be overloaded when creating a custom class. It is called with this component as a context manager (i.e. it is the active component), and it receives any positional arguments that were passed to the constructor.

reaction(*connection_strings)

Create a reaction by connecting a function to one or more events of this instance. Can also be used as a decorator. See the reaction decorator, and the intro docs for more information.

flexx.event.mutate_array(array, ev)

Function to mutate a list- or array-like property in-place. Used by Component. The ev must be a dict with elements:

  • mutation: ‘set’, ‘insert’, ‘remove’ or ‘replace’.
  • objects: the values to set/insert/replace, or the number of iterms to remove.
  • index: the (non-negative) index to insert/replace/remove at.
flexx.event.mutate_dict(d, ev)

Function to mutate an dict property in-place. Used by Component. The ev must be a dict with elements:

  • mutation: ‘set’, ‘insert’, ‘remove’ or ‘replace’.
  • objects: the dict to set/insert/replace, or a list if keys to remove.
  • index: not used.

Attributes

class flexx.event.Attribute(doc='')

Attributes are (readonly, and usually static) values associated with Component classes. They expose and document a value without providing means of observing changes like Property does. (The actual value is taken from component._xx, with “xx” the name of the attribute.)

Properties

class flexx.event.Property(*args, doc='', settable=False)

Base property class. Properties are (readonly) attributes associated with Component classes, which can be mutated only by actions. The base Property class can have any value, the subclasses validate/convert the value when it is mutated.

Parameters:
  • initial_value – The initial value for the property. If omitted, a default value is used (specific for the type of property).
  • settable (bool) – If True, a corresponding setter action is automatically created that can be used to set the property. Default False.
  • doc (str) – The documentation string for this property (optional).

Example usage:

class MyComponent(event.Component):

    foo = event.AnyProp(7, doc="A property that can be anything")
    bar = event.StringProp(doc='A property that can only be string')
    spam = event.IntProp(8, settable=True)

>> c = MyComponent()
>> c.set_spam(9)  # use auto-generated setter action

One can also implement custom properties:

class MyCustomProp(event.Property):
    ''' A property that can only be 'a', 'b' or 'c'. '''

    _default = 'a'

    def _validate(self, value, name, data):
        if value not in 'abc':
            raise TypeError('MyCustomProp %r must be "a", "b" or "c".' % name)
        return value
class flexx.event.AnyProp(*args, doc='', settable=False)

A property that can be anything (like Property). Default None.

class flexx.event.BoolProp(*args, doc='', settable=False)

A property who’s values are converted to bool. Default False.

class flexx.event.TriStateProp(*args, doc='', settable=False)

A property who’s values can be False, True and None.

class flexx.event.IntProp(*args, doc='', settable=False)

A propery who’s values are integers. Floats and strings are converted. Default 0.

class flexx.event.FloatProp(*args, doc='', settable=False)

A propery who’s values are floats. Integers and strings are converted. Default 0.0.

class flexx.event.StringProp(*args, doc='', settable=False)

A propery who’s values are strings. Default empty string.

class flexx.event.TupleProp(*args, doc='', settable=False)

A propery who’s values are tuples. In JavaScript the values are Array objects that have some of their methods disabled. Default empty tuple.

class flexx.event.ListProp(*args, doc='', settable=False)

A propery who’s values are lists. Default empty list. The value is always copied upon setting, so one can safely provide an initial list.

Warning: updating the list in-place (e.g. use append()) will not trigger update events! In-place updates can be done via the _mutate method.

class flexx.event.DictProp(*args, doc='', settable=False)

A property who’s values are dicts. Default empty dict. The value is always copied upon setting, so one can safely provide an initial dict.

Warning: updating the dict in-place (e.g. use update()) will not trigger update events! In-place updates can be done via the _mutate method.

class flexx.event.ComponentProp(*args, doc='', settable=False)

A propery who’s values are Component instances or None. Default None.

class flexx.event.FloatPairProp(*args, doc='', settable=False)

A property that represents a pair of float values, which can also be set using a scalar.

class flexx.event.EnumProp(*args, doc='', settable=False)

A property that represents a choice between a fixed set of (string) values.

Useage: foo = EnumProp(['optionA', 'optionB', ...], 'default', ...). If no initial value is provided, the first option is used.

class flexx.event.ColorProp(*args, doc='', settable=False)

A property that represents a color. The value is represented as a (dict-like) object that has the following attributes:

  • t: a 4-element tuple (RGBA) with values between 0 and 1.
  • css: a CSS string in the form ‘rgba(r,g,b,a)’.
  • hex: a hex RGB color in the form ‘#rrggbb’ (no transparency).
  • alpha: a scalar between 0 and 1 indicating the transparency.

The color can be set using:

  • An object as described above.
  • A tuple (length 3 or 4) with floats between 0 and 1.
  • A hex RGB color like ‘#f00’ or ‘#aa7711’.
  • A hex RGBA color like ‘#f002’ or ‘#ff000022’.
  • A CSS string “rgb(…)” or “rgba(…)”
  • Simple Matlab-like names like ‘k’, ‘w’, ‘r’, ‘g’, ‘b’, etc.
  • A few common color names like ‘red’, ‘yellow’, ‘cyan’.
  • Further, string colors can be prefixed with “light”, “lighter”, “dark” and “darker”.
  • Setting to None or “” results in fully transparent black.

Actions

flexx.event.action(func)

Decorator to turn a method of a Component into an Action.

Actions change the state of the application by mutating properties. In fact, properties can only be changed via actions.

Actions are asynchronous and thread-safe. Invoking an action will not apply the changes directly; the action is queued and handled at a later time. The one exception is that when an action is invoked from anoher action, it is handled directly.

Although setting properties directly might seem nice, their use would mean that the state of the application can change while the app is reacting to changes in the state. This might be managable for small applications, but as an app grows this easily results in inconsistencies and bugs. Separating actions (which modify state) and reactions (that react to it) makes apps easier to understand and debug. This is the core idea behind frameworks such as Elm, React and Veux. And Flexx adopts it as well.

Example usage:

class MyComponent(event.Component):

    count = event.IntProp(0)

    @action
    def increase_counter(self):
        self._mutate_count(self.count + 1)  # call mutator function
class flexx.event.Action(ob, func, name, doc)

Action objects are wrappers around Component methods. They take care of queueing action invokations rather than calling the function directly, unless the action is called from another action (in this case it would a direct call). This class should not be instantiated directly; use event.action() instead.

Reactions

flexx.event.reaction(*connection_strings, mode='normal')

Decorator to turn a method of a Component into a Reaction.

A reaction can be connected to multiple event types. Each connection string represents an event type to connect to.

Also see the Component.reaction() method.

class MyObject(event.Component):

    @event.reaction('first_name', 'last_name')
    def greet(self, *events):
        print('hello %s %s' % (self.first_name, self.last_name))

A reaction can operate in a few different modes. By not specifying any connection strings, the mode is “auto”: the reaction will automatically trigger when any of the properties used in the function changes. See get_mode() for details.

Connection string follow the following syntax rules:

  • Connection strings consist of parts separated by dots, thus forming a path. If an element on the path is a property, the connection will automatically reset when that property changes (a.k.a. dynamism, more on this below).
  • Each part can end with one star (‘*’), indicating that the part is a list and that a connection should be made for each item in the list.
  • With two stars, the connection is made recursively, e.g. “children**” connects to “children” and the children’s children, etc.
  • Stripped of ‘*’, each part must be a valid identifier (ASCII).
  • The total string optionally has a label suffix separated by a colon. The label itself may consist of any characters.
  • The string can have a “!” at the very start to suppress warnings for connections to event types that Flexx is not aware of at initialization time (i.e. not corresponding to a property or emitter).

An extreme example could be "!foo.children**.text:mylabel", which connects to the “text” event of the children (and their children, and their children’s children etc.) of the foo attribute. The “!” is common in cases like this to suppress warnings if not all children have a text event/property.

class flexx.event.Reaction(ob, func, mode, connection_strings)

Reaction objects are wrappers around Component methods. They connect to one or more events. This class should not be instantiated directly; use event.reaction() or Component.reaction() instead.

dispose()

Disconnect all connections so that there are no more references to components.

get_connection_info()

Get a list of tuples (name, connection_names), where connection_names is a list of type names (including label) for the made connections.

get_mode()

Get the mode for this reaction:

  • ‘normal’: events are handled in the order that they were emitted. Consequently, there can be multiple calls per event loop iteration if other reactions were triggered as well.
  • ‘greedy’: this reaction receives all its events (since the last event loop iteration) in a single call (even if this breaks the order of events with respect to other reactions). Use this when multiple related events must be handled simultenously (e.g. when syncing properties).
  • ‘auto’: this reaction tracks what properties it uses, and is automatically triggered when any of these properties changes. Like ‘greedy’ there is at most one call per event loop iteration. Reactions with zero connection strings always have mode ‘auto’.

The ‘normal’ mode generally offers the most consistent behaviour. The ‘greedy’ mode allows the event system to make some optimizations. Combined with the fact that there is at most one call per event loop iteration, this can provide higher performance where it matters. Reactions with mode ‘auto’ can be a convenient way to connect things up. Although it allows the event system to make the same optimizations as ‘greedy’, it also needs to reconnect the reaction after each time it is called, which can degregade performance especially if many properties are accessed by the reaction.

get_name()

Get the name of this reaction, usually corresponding to the name of the function that this reaction wraps.

reconnect(index)

(re)connect the index’th connection.

Emitter

flexx.event.emitter(func)

Decorator to turn a method of a Component into an Emitter.

An emitter makes it easy to emit specific events, and is also a placeholder for documenting an event.

class MyObject(event.Component):

   @emitter
   def spam(self, v):
        return dict(value=v)

m = MyObject()
m.spam(42)  # emit the spam event

The method being decorated can have any number of arguments, and should return a dictionary that represents the event to generate. The method’s docstring is used as the emitter’s docstring.

class flexx.event.Emitter(ob, func, name, doc)

Emitter objects are wrappers around Component methods. They take care of emitting an event when called and function as a placeholder for documenting an event. This class should not be instantiated directly; use event.emitter() instead.

Dict

class flexx.event.Dict

A dict in which the items can be get/set as attributes.

This provides a lean way to represent structured data, and works well in combination with autocompletion. Keys can be anything that are otherwise valid keys, but keys that are not valid identifiers or that are methods of the dict class (e.g. ‘items’ or ‘copy’) can only be get/set in the classic way.

Example:

>> d = Dict(foo=3)
>> d.foo
3
>> d['foo'] = 4
>> d.foo
4
>> d.bar = 5
>> d.bar
5

loop

class flexx.event.Loop

The singleton Flexx event loop at flexx.event.loop. This holds the queue of pending calls, actions, and reactions. These are queued separately to realize a consistent one-way data-flow. Further, this object keeps track of (per thread) active components (i.e. the components whose context manager is currently active).

Users typically do not need to be aware of the loop object, as it is used internally by Flexx, though it can be useful during debugging.

This event system integrates with Python’s builtin asyncio system, configurable via Loop.integrate(). This system can run in a separate thread, but there can be only one active flexx event loop per process.

This object can also be used as a context manager; an event loop iteration takes place when the context exits.

add_action_invokation(action, args)

Schedule the handling of an action. Automatically called when an action object is called.

add_reaction_event(reaction, ev)

Schulde the handling of a reaction. Automatically called by components.

call_soon(func, *args)

Arrange for a callback to be called as soon as possible. The callback is called after call_soon() returns, when control returns to the event loop.

This operates as a FIFO queue, callbacks are called in the order in which they are registered. Each callback will be called exactly once.

Any positional arguments after the callback will be passed to the callback when it is called.

This method is thread-safe: the callback will be called in the thread corresponding with the loop. It is therefore actually more similar to asyncio’s call_soon_threadsafe().

Also see asyncio.get_event_loop().call_soon() and asyncio.get_event_loop().call_later().

can_mutate(component=None)

Whether mutations can be done to the given component, and whether invoked actions on the component are applied directly.

get_active_component()

Get the currently “active” component (for this thread), or None.

get_active_components()

Get a tuple that represents the stack of “active” components. Each thread has its own stack. Should only be used directly inside a Component context manager.

has_pending()

Get whether there are any pending actions, reactions, or calls.

integrate(loop=None, reset=True)

Integrate the Flexx event system with the given asyncio event loop (or the default one). Also binds the event system to the current thread.

From this point, any (pending) calls to the iter callback by the previous thread will be ignored.

By calling this without calling reset(), it should be possible to hot-swap the system from one loop (and/or thread) to another (though this is currently not tested).

iter()

Do one event loop iteration; process pending calls, actions and reactions. These tree types of items are each queued in separate queues, and are handled in the aforementioned order.

register_prop_access(component, prop_name)

Register access of a property, to keep track of automatic reactions.

reset()

Reset the loop, purging all pending calls, actions and reactions. This is mainly intended for test-related code.