docs(Widget Tree): provide data lost from end of doc (#9158)

This commit is contained in:
Victor Wheeler
2025-11-24 01:30:04 -07:00
committed by GitHub
parent e78eb2b985
commit e40b55706f
@@ -7,17 +7,17 @@ Widget Tree
Parents and Children
********************
LVGL stores widgets in a parent-child structure (tree).
The root element is the screen, which has no parent.
LVGL stores Widgets in a parent-child structure (tree).
The root element is the Screen, which has no parent.
When a widget is created, a pointer to its parent is passed to the create function.
When a Widget is created, a pointer to its parent is passed to the create function.
LVGL provides many useful functions to modify the widget tree and get information about it:
LVGL provides many useful functions to modify the Widget tree and get information about it:
- :cpp:expr:`lv_obj_get_screen(widget)`: Get a widget's screen ("root" parent).
- :cpp:expr:`lv_obj_get_parent(widget)`: Get the widget's current parent.
- `lv_obj_set_parent(widget, new_parent)`: Move the widget to a new parent.
The widget will become the top-most (last/youngest) child of the new parent.
- :cpp:expr:`lv_obj_get_screen(widget)`: Get a Widget's screen ("root" parent).
- :cpp:expr:`lv_obj_get_parent(widget)`: Get the Widget's current parent.
- `lv_obj_set_parent(widget, new_parent)`: Move the Widget to a new parent.
The Widget will become the top-most (last/youngest) child of the new parent.
- :cpp:expr:`lv_obj_get_child(parent, idx)`: Return a specific child of a parent.
Some examples for ``idx``:
@@ -26,13 +26,13 @@ LVGL provides many useful functions to modify the widget tree and get informatio
- ``-1``: get the last created child
- :cpp:expr:`lv_obj_get_child_by_type(parent, idx, &lv_slider_class)`: Similar to :cpp:expr:`lv_obj_get_child` but filters to children
with a given type.
- :cpp:expr:`lv_obj_find_by_name(parent, "text")`: Find a widget with a given name under a parent. It does not have to be a direct child.
- :cpp:expr:`lv_obj_get_child_by_name(parent, "container/button/text")`: Get a widget by navigating a path using parent names (separated by ``/``).
- :cpp:expr:`lv_obj_get_index(widget)`: Return the index of the widget in its parent.
- :cpp:expr:`lv_obj_find_by_name(parent, "text")`: Find a Widget with a given name under a parent. It does not have to be a direct child.
- :cpp:expr:`lv_obj_get_child_by_name(parent, "container/button/text")`: Get a Widget by navigating a path using parent names (separated by ``/``).
- :cpp:expr:`lv_obj_get_index(widget)`: Return the index of the Widget in its parent.
It is equivalent to the number of older siblings in the parent.
- :cpp:expr:`lv_obj_move_to_index(widget, idx)`: Move the widget to a specified index.
- :cpp:expr:`lv_obj_move_to_index(widget, idx)`: Move the Widget to a specified index.
``0`` is the oldest child's position, ``-1`` is the youngest.
- :cpp:expr:`lv_obj_swap(widget1, widget2)`: Swap the positions of two widgets.
- :cpp:expr:`lv_obj_swap(widget1, widget2)`: Swap the positions of two Widgets.
To iterate through a parent widget's children:
@@ -52,23 +52,26 @@ To iterate through a parent widget's children:
Names
*****
When a widget is created, its reference can be stored in an :cpp:expr:`lv_obj_t *` pointer
variable. To use this widget in multiple places in the code, the variable can be passed
When a Widget is created, its reference can be stored in an :cpp:expr:`lv_obj_t *` pointer
variable. To use this Widget in multiple places in the code, the variable can be passed
as a function parameter or made global. However, this approach has some drawbacks:
- Using global variables adds names to the global namespace and is thus generally not recommended.
- It's not scalable. Passing references to 20 widgets as function parameters is not ideal.
- Tracking whether a widget still exists or has been deleted requires extra logic and can be tricky.
- It's not scalable. Passing references to 20 Widgets as function parameters is not ideal.
- Tracking whether a Widget still exists or has been deleted requires extra logic and can be tricky.
.. _tree_setting_names:
Setting Names
-------------
To address these issues, LVGL introduces a powerful widget naming system that can be enabled
To address these issues, LVGL introduces a powerful Widget naming system that can be enabled
by setting ``LV_USE_OBJ_NAME`` in ``lv_conf.h``.
A custom name can be assigned using :cpp:expr:`lv_obj_set_name(obj, "name")` or
:cpp:expr:`lv_obj_set_name_static(obj, "name")`. The "static" variant requires that the passed
name remains valid while the widget exists, since only the pointer is stored. Otherwise, LVGL will
name remains valid while the Widget exists, since only the pointer is stored. Otherwise, LVGL will
allocate memory to store a copy of the name.
If a name ends with ``#``, LVGL will automatically replace it with an index based on the
@@ -83,7 +86,7 @@ Below is an example showing how manually and automatically assigned names are re
- ``lv_label`` with no name: "lv_label_0"
- ``lv_label`` named ``"title"``: "title"
- ``lv_label`` with no name: "lv_label_1" (It's the third label, but custom-named widgets are not counted)
- ``lv_label`` with no name: "lv_label_1" (It's the third label, but custom-named Widgets are not counted)
- ``lv_obj`` container named ``"buttons"``:
@@ -97,6 +100,12 @@ Below is an example showing how manually and automatically assigned names are re
- ``lv_button`` named ``mybtn_#``: "mybtn_2"
- ``lv_button`` named ``mybtn_#``: "mybtn_3"
Note that these indices are "fluid", meaning if "mybtn_2" above is deleted, the button
previously known as "mybtn_3" will thereafter be known as "mybtn_2", since the
indices are resolved *when names are being found by name*, not when they are set.
Keep this in mind when Finding Widgets as described below.
Finding Widgets
---------------
@@ -104,4 +113,28 @@ Widgets can be found by name in two ways:
1. **Get a direct child by name** using :cpp:expr:`lv_obj_get_child_by_name(parent, "child_name")`.
Example:
:cpp:expr:`lv_obj_get_child_by_name(header, "title")`
:cpp:expr:`lv_obj_get_child_by_name(header, "title")`.
You can also use a path to find nested children:
:cpp:expr:`lv_obj_get_child_by_name(cont, "buttons/mybtn_2")`.
2. **Find a descendant at any level** using :cpp:expr:`lv_obj_find_by_name(parent, "child_name")`.
Example:
:cpp:expr:`lv_obj_find_by_name(cont, "mybtn_1")`
Note that ``"mybtn_1"`` is a child of ``cont`` at any level, not necessarily a
direct child. This is useful when you want to ignore the hierarchy and search by
name alone.
Since both functions start searching from a specific parent, it's possible to have
multiple Widget subtrees with identical names under different parents.
For example, if ``my_listitem_create(parent)`` creates a Widget named ``"list_item_#"``
with direct children ``"icon"``, ``"title"``, ``"ok_button"``, and ``"lv_label_0"``,
and it is called 10 times, a specific ``"ok_button"`` can be found like this:
.. code-block:: c
lv_obj_t * item = lv_obj_find_by_name(lv_screen_active(), "list_item_5");
lv_obj_t * ok_btn = lv_obj_find_by_name(item, "ok_button");
// Or
lv_obj_t * ok_btn = lv_obj_get_child_by_name(some_list_container, "list_item_5/ok_button");