Development docs. Unreleased and may change.Switch to Release v9.6.0

Observers

Learn more about Observers.

Edit on GitHub

An Observer watches one Subject and runs a callback whenever that Subject's value changes. When you subscribe, the callback is also called once immediately, so the Observer can pick up the current value right away.

A callback always has the same signature:

 
static void temperature_cb(lv_observer_t * observer, lv_subject_t * subject)
{
    int32_t t = lv_subject_get_int(subject);
    LV_LOG_USER("Temperature is now %d", t);
}

Subscribing

The simplest way to subscribe is lv_subject_add_observer(). The third argument is free-form user data passed to the callback:

 
lv_subject_add_observer(temperature, temperature_cb, NULL);

Often the Observer needs to update a specific object. Pass a Widget with lv_subject_add_observer_obj(), then read it back in the callback with lv_observer_get_target_obj().

 
lv_subject_add_observer_obj(temperature, label_cb, my_label, NULL);

static void label_cb(lv_observer_t * observer, lv_subject_t * subject)
{
    lv_obj_t * label = lv_observer_get_target_obj(observer);
    lv_label_set_text_fmt(label, "%d °C", lv_subject_get_int(subject));
}

In a generic case any other pointer can be passed as target with lv_subject_add_observer_with_target() and the target can be read back with lv_observer_get_target().

Unsubscribing

An Observer bound to a Widget using lv_subject_add_observer_obj() is removed automatically when that Widget is deleted, so in this case you don't need to do anything. Otherwise:

Binding a Widget to a Subject

Besides subscribing by hand, a Widget's property can be bound to a Subject directly. Each binding is just an Observer, so it too is removed automatically when the Widget is deleted.

Flags

To drive a flag from a 0/non-zero Subject, use lv_obj_bind_bool(). Because the callback takes a bool, a dedicated per-flag setter can be passed straight in:

 
lv_obj_bind_bool(widget, subject, lv_obj_set_hidden);   /* hidden while non-zero */

States

There's no dedicated setter for a state, and states often depend on a comparison, so bind them with a small Observer of your own:

 
static void disabled_cb(lv_observer_t * observer, lv_subject_t * subject)
{
    lv_obj_t * obj = lv_observer_get_target_obj(observer);
    lv_obj_set_state(obj, LV_STATE_DISABLED, lv_subject_get_int(subject) > 80);
}

lv_subject_add_observer_obj(subject, disabled_cb, widget, NULL);

The older lv_obj_bind_flag_if_* and lv_obj_bind_state_if_* functions are deprecated in favor of the two approaches above.

Checked state

lv_obj_bind_checked() creates a two-way binding: the Widget's checked state follows the Subject (checked while non-zero), and clicking the Widget writes 1 or 0 back to the Subject. The Widget should have lv_obj_set_checkable(obj, true) to make it checkable.

 
lv_obj_bind_checked(checkbox, subject);

Widget values

A Widget's main value or text is bound with the widget's own lv_<widget>_bind_...() function, described under "Data binding" on each widget's page. A few examples:

Label text

lv_label_bind_text() keeps a Label's text in sync with a Subject, optionally through a printf-style format string.

Slider value

lv_slider_bind_value() ties a Slider's position to a Subject; dragging the Slider updates the Subject and vice versa.

Arc value

lv_arc_bind_value() keeps an Arc's value in sync with a Subject.

lv_dropdown_bind_value() binds the selected option's index to a Subject.

Roller value

lv_roller_bind_value() binds the selected option's index to a Subject.

Last updated on

On this page