# Widgets (/syntax/widgets)



Widgets are fundamental building blocks for creating reusable UI components alongside Components and Screens.

Overview [#overview]

A Widget in LVGL Pro is defined using an XML file with a `widget` root element. Widgets provide a way to encapsulate UI behavior and appearance into reusable units that can be nested within other Widgets and Components.

Supported Child Elements [#supported-child-elements]

Widget definitions support these child XML tags:

* `consts` - Define constant values for the widget
* `api` - Define the widget's public API and properties
* `styles` - Define styling rules and themes
* `view` - Define the widget's visual structure and layout
* `previews` - Define preview configurations for the Editor

Relationship to Components [#relationship-to-components]

Just like Components, Widgets can contain other Widgets and Components as children, allowing you to build complex hierarchies of nested UI elements.

Loading and Parsing [#loading-and-parsing]

Widgets cannot be instantiated directly from XML in the final application. Instead, each Widget requires an XML parser that maps XML attributes to C function calls. LVGL provides:

* Built-in XML parsers for standard widgets
* Helper functions and required libraries for custom parsers
* [Many XML parser examples](https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers) for reference

Built-in Widgets [#built-in-widgets]

The built-in LVGL widgets such as `lv_slider`, `lv_label`, and `lv_chart` already include XML parsers, making them directly available for use in XML files.

Example Usage [#example-usage]

```xml title="xml" lineNumbers=1
<component>
  <view>
    <lv_label x="10" text="Hello"/>
  </view>
</component>
```

Built-in Widget Structure [#built-in-widget-structure]

Each built-in widget consists of three components:

* **C Implementation** - Pure C code defining the widget behavior (e.g., [lv\_slider.c](https://github.com/lvgl/lvgl/tree/master/src/widgets/slider/lv_slider.c))
* **XML Definition** - An XML schema file used by the Editor for validation and autocomplete (e.g., [lv\_slider.xml](https://github.com/lvgl/lvgl/blob/master/xmls/lv_slider.xml))
* **XML Parser** - A C parser file that maps XML attributes to C function calls (e.g., [lv\_xml\_slider\_parser.c](https://github.com/lvgl/lvgl/blob/master/src/others/xml/parsers/lv_xml_slider_parser.c))

XML Parser [#xml-parser]

Creating a Custom Parser [#creating-a-custom-parser]

To make custom Widgets accessible from XML, you need to create and register an XML parser. The parser translates XML attributes into C function calls.

Here's an example parser for a label widget:

```c title=" " lineNumbers=1
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs)
{
  /* Create the label */
  void * obj = lv_label_create(lv_xml_state_get_parent(state));
  return obj;
}

void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
  void * obj = lv_xml_state_get_item(state);

  /* Apply the common properties, e.g., width, height, styles, flags, etc. */
  lv_xml_obj_apply(state, attrs);

  /* Process the label-specific attributes */
  for(int i = 0; attrs[i]; i += 2) {
    const char * name = attrs[i];
    const char * value = attrs[i + 1];

    if(lv_streq("text", name)) lv_label_set_text(obj, value);
    if(lv_streq("long_mode", name)) lv_label_set_long_mode(obj, long_mode_text_to_enum(value));
    /* Process more props here ... */
  }
}

/* Helper to convert strings to enum values */
static lv_label_long_mode_t long_mode_text_to_enum(const char * txt)
{
  if(lv_streq("wrap", txt)) return LV_LABEL_LONG_MODE_WRAP;
  if(lv_streq("scroll", txt)) return LV_LABEL_LONG_MODE_SCROLL;

  LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
  return 0; /* Return 0 in the absence of a better option. */
}
```

The key pattern is using `if(lv_streq("property", name)) lv_function_set(obj, value);` to map any XML attribute to its corresponding C function call.

Creating Widgets in LVGL Pro Editor [#creating-widgets-in-lvgl-pro-editor]

Using the Editor vs Manual Coding [#using-the-editor-vs-manual-coding]

While you can create widgets by writing C code manually (similar to built-in LVGL widgets), using LVGL Pro Editor is significantly faster and simpler.

Generated Files [#generated-files]

When you create an XML file with a `widget` root element, the Editor automatically generates the following C/H files:

**Generated on Export (Overwritten Each Time):**

* `<widget_name>_gen.h` - Contains the generated API implementation
* `<widget_name>_private_gen.h` - Contains private API and internal data structures
* `<widget_name>_gen.c` - Contains widget internals including constructor, destructor, and event handlers

**User-Editable (Created Once, Preserved):**

* `<widget_name>.h` - Header file that includes `widget_name_gen.h` and allows custom API definitions
* `<widget_name>.c` - Implementation file containing hooks for custom code
* `<widget_name>_xml_parser.c` - XML parser skeleton for processing widget attributes

Custom Code Hooks [#custom-code-hooks]

The `<widget_name>.c` file contains three extension hooks:

* **Constructor Hook** - Called when the widget and all its children are created, allowing modifications to child elements
* **Destructor Hook** - Called when the widget is deleted, for freeing manually allocated memory
* **Event Hook** - Called at the beginning of the widget's event callback for custom actions

This C file also contains implementations for all setter functions defined in the widget's API. Declarations are automatically exported in `<widget_name>_gen.h`.

Widget Elements [#widget-elements]

Elements are internal dynamic parts of a widget that can be accessed or created at runtime. Examples include:

* Tabs in a tabview
* List items in a dropdown
* Series in a chart

Elements are defined in the `api` tag of your widget's XML, just like other API properties. For detailed information, see the widget element documentation.
