Listeners
Live’s observable properties expose a callback-based subscription model. To listen for changes on a property, call the listener methods bound on its owning class — three are bound per observable property, derived from the property name:
add_<prop>_listener(callback)remove_<prop>_listener(callback)<prop>_has_listener(callback)The shape is uniform across the LOM — every observable property exposes the same three methods, with the same callback semantics (covered in detail below).
Subscribing
Section titled “Subscribing”Register a callback with add_<prop>_listener(callback). Live fires
the callback when the property’s value changes. The callback is
invoked with no arguments — it’s a notification that a change
occurred, not a delivery of the new value. Read the current value
by accessing the property on the owning object:
def on_tempo_change(): print(song.transport.tempo)
song.transport.add_tempo_listener(on_tempo_change)Deregister via remove_<prop>_listener(callback). Removal matches
by object identity — the same function reference must be passed to
both add and remove. Inspect via <prop>_has_listener(callback),
returning bool.
Lifetime: keep callbacks alive
Section titled “Lifetime: keep callbacks alive”Live holds the registered callback for as long as the subscription
is active, but Python’s garbage collector doesn’t know about that
reference. If the only Python-side handle on the callback is the
one inside the add_..._listener(callback) call itself, the
function may be reclaimed when its surrounding scope exits — and
the subscription becomes silently inert.
Stash callbacks somewhere with a stable lifetime: a module-level
variable, an attribute on a long-lived object, or a ListenerVector
(the bookkeeping container documented below — collects multiple
handles for bulk lifetime management).
Bound methods are particularly fragile. self.on_tempo_change
creates a fresh bound-method instance on every attribute access:
song.transport.add_tempo_listener(self.on_tempo_change)...song.transport.remove_tempo_listener(self.on_tempo_change)# ↑ different bound-method instance — does not match the registrationBind once, store the reference, pass that reference to both add
and remove:
self._on_tempo_change = self.on_tempo_changesong.transport.add_tempo_listener(self._on_tempo_change)...song.transport.remove_tempo_listener(self._on_tempo_change)Threading
Section titled “Threading”Listener attachment runs on Live’s main thread. Callback invocation fires synchronously when Live decides the property has changed, presumed (but unverified) to also run on Live’s main thread. Don’t block inside a callback — long-running work in a synchronous handler stalls the message pump that delivers the next event. Compute, queue for a worker, and return.
When the underlying object is destroyed
Section titled “When the underlying object is destroyed”Listeners are bound to a LomObject instance. When the C++ side
destroys the underlying object — track deleted, clip removed, Set
closed — Live does not call the listener to notify of the
destruction. Subsequent attribute reads on the
destroyed-but-still-Python-referenced LomObject typically raise;
the subscription is simply silently inert.
Code that needs to unwind subscriptions on destruction has to
detect it by other means — typically by listening on a parent
collection (e.g. Song.tracks’s listener fires on track deletion,
with the deleted track no longer in the returned list).
Listener-only triplets
Section titled “Listener-only triplets”Not every listener triplet has a readable attribute behind it.
Clip binds add_playing_status_listener /
remove_playing_status_listener / playing_status_has_listener
to fire when a clip’s transport state changes — triggered,
playing, recording, stopped — but clip.playing_status itself
isn’t a Python attribute. The state is read through related
properties (Clip.is_playing / is_recording / is_triggered)
and changes through methods (fire, stop); the listener fires
on those changes. The “playing_status” in the triplet name is
the conceptual thing being observed, not a property to read.
Same shape on Clip.notes, Clip.loop_jump, Track.data,
Song.data, and a handful of others. Each owning class surfaces
these in a dedicated #### Listener Only section on its
reference page — separate from the regular Properties list so
the missing type annotation isn’t read as missing data. The
subscription mechanism is identical to value-bearing observable
properties; the difference is in how you read state, not in how
you listen.
Bookkeeping types
Section titled “Bookkeeping types”ListenerHandle and ListenerVector are the runtime classes
Live’s binding exposes for managing subscriptions in aggregate.
Documented below; relevant when a long-lived component manages
many subscriptions and wants a single container for their
lifetimes.
Classes
Section titled “Classes”ListenerHandle
Section titled “ListenerHandle”This class represents a Python listener when connected to a Live property. From Live’s runtime docstring.
Properties
Section titled “Properties”listener_func: Callablehigh confidence- docstring “Returns the original function” — functions are Callable.
Section titled “listener_func: Callablehigh confidencedocstring “Returns the original function” — functions are Callable.”Returns the original function From Live’s runtime docstring.
listener_self: Anymedium confidence- docstring “weak reference to original self, if it was a bound method” — can be any object instance (or None for non-bound functions).
Any is appropriately broad but could be Any | None if probed.
Section titled “listener_self: Anymedium confidencedocstring “weak reference to original self, if it was a bound method” — can be any object instance (or None for non-bound functions). Any is appropriately broad but could be Any | None if probed.”Any is appropriately broad but could be Any | None if probed.Returns the weak reference to original self, if it was a bound method From Live’s runtime docstring.
name: strmedium confidence- docstring “Prints the name of the property that this listener is connected to” — boost.python doc-style “Prints” implies a printable string return on a property access (returns the property name as a string). ListenerHandle is internal-only (zero corpus references); raw_doc is the strongest evidence available.
Section titled “name: strmedium confidencedocstring “Prints the name of the property that this listener is connected to” — boost.python doc-style “Prints” implies a printable string return on a property access (returns the property name as a string). ListenerHandle is internal-only (zero corpus references); raw_doc is the strongest evidence available.”Prints the name of the property that this listener is connected to From Live’s runtime docstring.
Methods
Section titled “Methods”disconnect()
Section titled “disconnect()”Disconnects the listener from its property From Live’s runtime docstring.
ListenerVector
Section titled “ListenerVector”A read only container for accessing a list of listeners. From Live’s runtime docstring.
Methods
Section titled “Methods”append()
Section titled “append()”- value: ListenerHandle
extend()
Section titled “extend()”- values: Iterable[ListenerHandle]
This is an independent reference site. Not affiliated with, endorsed by, or sponsored by Ableton AG. “Ableton”, “Live”, “Push”, and related marks are trademarks of Ableton AG.