Widgets
Learn how to create and use widgets as reusable UI components with XML-based definition and automatic code generation.
Widgets are fundamental building blocks for creating reusable UI components alongside Components and Screens.
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
Widget definitions support these child XML tags:
consts- Define constant values for the widgetapi- Define the widget's public API and propertiesstyles- Define styling rules and themesview- Define the widget's visual structure and layoutpreviews- Define preview configurations for the Editor
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
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 for reference
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
<component>
<view>
<lv_label x="10" text="Hello"/>
</view>
</component>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)
- XML Definition - An XML schema file used by the Editor for validation and autocomplete (e.g., lv_slider.xml)
- XML Parser - A C parser file that maps XML attributes to C function calls (e.g., lv_xml_slider_parser.c)
XML 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:
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
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
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 includeswidget_name_gen.hand 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
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
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.
How is this guide?
Last updated on