## 1. Quick Start
-
Download and flash the firmware according to the ESP32 MicroPython Tutorial.
-
Upload the corresponding screen driver (screen.py) to the MicroPython device.
-
Copy the following code into Thonny, click to run the script, and you will see the display effect on the screen.
import screen
import lvgl as lv
scr = lv.screen_active()# Get the currently active screen object
scr.set_style_bg_color(lv.color_hex(0x000000), 0)# Set the screen background color to black
slider = lv.slider(scr)# Create a slider
slider.set_size(100, 25)# Set the slider size to 300 (width) x 50 (height)
slider.center()# Center the slider
label = lv.label(scr)# Create a label
label.set_text('HELLO LVGL_MICROPYTHON!')# Label content
label.align(lv.ALIGN.CENTER, 0, -50)# Align the label to the center of the screen and offset upward by 50
Display Effect

2. Display Cases
2.1 Analog Clock
import screen
import time
import lvgl as lv
from machine import Timer
import math
scrn = lv.screen_active()
scrn.set_style_bg_color(lv.color_hex(0x000000), 0)
class AnalogClock:
def __init__(self, parent):
self.scale = None
self.second_hand = None
self.minute_hand = None
self.hour_hand = None
# Get current time
now = time.localtime()
self.hour = now[3] % 12 # Convert to 12-hour format
self.minute = now[4]
self.second = now[5]
self.create_clock(parent)
self.start_timer()
def create_clock(self, parent):
"""Create analog clock components"""
# Create clock dial body (keep size 120x120)
self.scale = lv.scale(parent)
self.scale.set_size(200, 200)
self.scale.set_mode(lv.scale.MODE.ROUND_INNER)
# Set clock dial style (unchanged)
self.scale.set_style_bg_opa(lv.OPA._60, 0)
self.scale.set_style_bg_color(lv.color_hex(0x222222), 0)
self.scale.set_style_radius(lv.RADIUS_CIRCLE, 0)
self.scale.set_style_clip_corner(True, 0)
self.scale.center()
# Configure scale system (unchanged)
self.scale.set_label_show(True)
hour_labels = ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", None]
self.scale.set_text_src(hour_labels)
self.scale.set_style_text_font(lv.font_montserrat_12, 0)
self.scale.set_total_tick_count(61)
self.scale.set_major_tick_every(5)
# Major tick style (unchanged)
style_indicator = lv.style_t()
style_indicator.init()
style_indicator.set_text_color(lv.color_hex(0xFFFFFF))
style_indicator.set_line_color(lv.color_hex(0xFFFFFF))
style_indicator.set_length(5)
style_indicator.set_line_width(2)
self.scale.add_style(style_indicator, lv.PART.INDICATOR)
# Minor tick style (unchanged)
style_minor = lv.style_t()
style_minor.init()
style_minor.set_line_color(lv.color_hex(0xAAAAAA))
style_minor.set_length(3)
style_minor.set_line_width(1)
self.scale.add_style(style_minor, lv.PART.ITEMS)
# Clock dial border style (unchanged)
style_main = lv.style_t()
style_main.init()
style_main.set_arc_color(lv.color_hex(0x222222))
style_main.set_arc_width(3)
self.scale.add_style(style_main, lv.PART.MAIN)
# Set range and angle (unchanged)
self.scale.set_range(0, 60)
self.scale.set_angle_range(360)
self.scale.set_rotation(270)
# Create second hand (red, length 90px, thin line)
self.second_hand = lv.line(self.scale)
self.second_hand.set_style_line_width(1, 0) # Thinner line width
self.second_hand.set_style_line_rounded(True, 0)
self.second_hand.set_style_line_color(lv.color_hex(0xFFFFFF), 0)
# Create minute hand (blue, length 75px)
self.minute_hand = lv.line(self.scale)
self.minute_hand.set_style_line_width(3, 0)
self.minute_hand.set_style_line_rounded(True, 0)
self.minute_hand.set_style_line_color(lv.color_hex(0x00BFFF), 0)
# Create hour hand (orange, length 60px)
self.hour_hand = lv.line(self.scale)
self.hour_hand.set_style_line_width(5, 0)
self.hour_hand.set_style_line_rounded(True, 0)
self.hour_hand.set_style_line_color(lv.color_hex(0xFFA500), 0)
# Add center point (unchanged)
center = lv.obj(self.scale)
center.set_size(8, 8) # Slightly reduce the size of the center point
center.center()
center.set_style_radius(lv.RADIUS_CIRCLE, 0)
center.set_style_bg_color(lv.color_hex(0xFFD700), 0)
center.set_style_bg_opa(lv.OPA.COVER, 0)
self.update_hands()
def update_hands(self):
"""Update the position of all hands"""
# Second hand (length 90px)
lv.scale.set_line_needle_value(self.scale, self.second_hand, 90, self.second)
# Minute hand (length 75px)
lv.scale.set_line_needle_value(self.scale, self.minute_hand, 75, self.minute)
# Hour hand (length 60px), considering minute offset
hour_value = self.hour * 5 + (self.minute // 12)
lv.scale.set_line_needle_value(self.scale, self.hour_hand, 60, hour_value)
def timer_callback(self, timer):
"""Timer callback (updates every second)"""
# Get current time
now = time.localtime()
self.hour = now[3] % 12
self.minute = now[4]
self.second = now[5]
self.update_hands()
def start_timer(self):
"""Start hardware timer (triggers every second)"""
self.timer = Timer(1)
self.timer.init(period=1000, mode=Timer.PERIODIC, callback=self.timer_callback)
# Create clock instance
clock = AnalogClock(scrn)
2.2 Menu Tab Page Switching
import lvgl as lv
import screen
scr = lv.screen_active()
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
def controls_create(parent):
parent.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
parent.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER,
lv.FLEX_ALIGN.CENTER)
# Button
btn = lv.button(parent)
btn.set_size(100, 50)
lbl = lv.label(btn)
lbl.set_text("Button")
lbl.center()
# Switch
sw = lv.switch(parent)
# Checkbox
cb = lv.checkbox(parent)
cb.set_text("Check")
# Slider + label
slider = lv.slider(parent)
slider.set_range(0, 100)
slider.set_value(40, False)
slider.set_size(150, 10)
lbl_val = lv.label(parent)
lbl_val.set_text("40")
slider.add_event_cb(lambda e: lbl_val.set_text(str(slider.get_value())),
lv.EVENT.VALUE_CHANGED, None)
# ---------- Visuals Page ----------
def visuals_create(parent):
parent.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
parent.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER,
lv.FLEX_ALIGN.CENTER)
# Line chart
chart = lv.chart(parent)
chart.set_size(220, 130)
chart.set_type(lv.chart.TYPE.LINE)
chart.set_point_count(8)
chart.set_div_line_count(3, 5)
ser1 = chart.add_series(lv.color_hex(0x01a2b1), lv.chart.AXIS.PRIMARY_Y)
ser2 = chart.add_series(lv.color_hex(0x44d1b6), lv.chart.AXIS.PRIMARY_Y)
for v in [10, 90, 30, 60, 10, 90, 30, 60]:
chart.set_next_value(ser1, v)
for v in [32, 66, 5, 47, 32, 66, 5, 47]:
chart.set_next_value(ser2, v)
# Arc
arc = lv.arc(parent)
arc.set_size(120, 120)
arc.set_range(0, 100)
arc.set_value(50)
# ---------- Selectors Page ----------
def selectors_create(parent):
parent.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
parent.set_flex_align(lv.FLEX_ALIGN.SPACE_EVENLY, lv.FLEX_ALIGN.CENTER,
lv.FLEX_ALIGN.CENTER)
# Calendar
cal = lv.calendar(parent)
cal.set_size(160, 160)
# Dropdown
dd = lv.dropdown(parent)
dd.set_options("Alpha\nBravo\nCharlie\nDelta")
dd.set_size(120, 40)
# Roller
roller = lv.roller(parent)
roller.set_options("A\nB\nC\nD\nE", lv.roller.MODE.NORMAL)
roller.set_size(120, 60)
# ---------- Main Interface ----------
tabview = lv.tabview(scr)
tabview.set_size(480, 320)
tab1 = tabview.add_tab("Controls")
tab2 = tabview.add_tab("Visuals")
tab3 = tabview.add_tab("Selectors")
controls_create(tab1)
visuals_create(tab2)
selectors_create(tab3)
Display Effect
Note: This display effect image is an online simulation image; the actual screen display color and size may vary.

3. Basic Knowledge
3.1 Objects
In LVGL (Light and Versatile Graphics Library), an Object is the core building block of the entire UI system and the foundation of all UI elements. It can be understood as the "basic unit" that constitutes the user interface.
Objects in LVGL have the following characteristics:
- Abstract concept: An object is an abstract concept representing elements that can be interacted with or displayed on the screen
- Inheritance relationship: All specific UI components (such as buttons, labels, sliders, etc.) are extended from the base object
- Rich attributes: Each object has basic attributes such as position, size, color, transparency, etc.
- Hierarchical structure: Objects can be nested within each other to form parent-child relationships, facilitating management of complex UIs
- Event-driven: Objects can respond to various events (such as clicks, swipes, etc.)
For example, when you create a button, it is essentially a special type of object that inherits all the attributes and methods of the base object while adding button-specific functionalities (such as pressed state, click events, etc.).
By manipulating objects, you can implement almost all UI functions: creating components, setting styles, handling interactions, etc.
3.2 States
In LVGL, a State is an attribute that describes the current behavior or interaction status of an object (such as buttons, sliders, and other UI components). It is used to control the appearance and behavior of objects in different scenarios. States affect the style performance of objects (such as color, size, transparency, etc.) and are the core mechanism for implementing interaction feedback.
Basic States
'''
DEFAULT # The default state style of the control, applied when no other state is triggered.
CHECKED # The style when the control is selected, applicable to controls with a "checked" state such as checkboxes and radio buttons.
FOCUSED # The style when the control has focus (e.g., selected via keyboard navigation or touch), usually indicating the currently interactive control.
FOCUS_KEY # The style when the control gains focus via the keyboard (e.g., Tab key), different from FOCUSED as it specifically targets keyboard-triggered focus.
EDITED # The style when the control is in edit mode, such as when a text field is activated and content is being entered.
HOVERED # The style when the mouse hovers over the control (only effective on mouse-supported devices), enhancing interaction on desktop or trackpad devices.
PRESSED # The style when the control is pressed (e.g., a button is clicked but not released), providing immediate visual feedback.
SCROLLED # The style when scrollable controls (such as lists, pages, scroll containers) are in a scrolling state, used to beautify visual effects during scrolling.
DISABLED # The style when the control is disabled, usually appearing grayscale or translucent, indicating the control is currently non-interactive.
USER_1 # User-defined state
USER_2 # User-defined state
USER_3 # User-defined state
USER_4 # User-defined state
ANY # Matches all states of the control
'''
Combined States
Objects can be combined through bitwise operations to be in multiple states simultaneously, for example:
- A button may be in both pressed and focused states (lv.STATE.PRESSED | lv.STATE.FOCUSED)
- A checkbox may be in both checked and disabled states (lv.STATE.CHECKED | lv.STATE.DISABLED)
3.3 Styles
In LVGL, a Style is the core mechanism for defining the appearance characteristics of UI objects. It is used to uniformly control the visual performance of interface elements such as colors, sizes, fonts, borders, etc. Through the style system, you can easily achieve beautiful and consistent UI designs and flexibly respond to visual changes under different states.
Core Features of Styles
- Attribute collection: A style is a collection of visual attributes covering various visual features such as background, border, text, spacing, etc.
- State binding: The same object can apply different styles under different states (such as default, pressed, selected) (e.g., a button changing color when pressed).
- Reuse and inheritance: A style can be shared by multiple objects and can also extend new styles based on existing ones, reducing duplicate definitions.
- Dynamic modification: Style attributes can be modified in real-time during runtime to achieve dynamic visual changes such as theme switching and animation effects.
LVGL provides rich style attributes to meet various visual needs. For more styles, see the "class style_t" section in the MicroPython LVGL API.py file.
Example: Using Styles with States
# Create a style. For more APIs, see the "class style_t" section in api.py
style_btn = lv.style_t()
# Set background color
style_btn.set_bg_color(lv.color_hex(0xFF0000))
# Apply as the style for the pressed state
btn.add_style(style_btn, lv.STATE.PRESSED)
3.4 Events
In LVGL, an Event is a mechanism for handling user interactions or system state changes, and is the core for implementing UI interaction logic. When a user operates a UI element (such as a button, slider, etc.) (click, swipe, etc.) or when an object's state changes, LVGL triggers corresponding events. Developers can respond to these events by registering event callback functions to implement specific functionalities. The following event types are available:
def btn_clicked(e): # Button click callback function
print("Button clicked!")
btn.add_event_cb(btn_clicked, lv.EVENT.CLICKED, None) # Set interaction callback function
# The following event types exist
'''
### Interaction-related events
PRESSED: Triggered when an object is pressed (e.g., a button is touched or clicked with a mouse).
PRESSING: Triggered repeatedly while an object is being pressed continuously (sent during the pressed state).
PRESS_LOST: Triggered when the input device (e.g., touch) accidentally leaves the object area while pressing the object.
SHORT_CLICKED: Triggered when released after a short press (press duration is shorter than the long press threshold).
SINGLE_CLICKED: Triggered by a single click (pressed and released).
DOUBLE_CLICKED: Triggered by a double click (two quick clicks).
TRIPLE_CLICKED: Triggered by a triple click (three quick clicks).
LONG_PRESSED: Triggered once when a long press reaches the threshold time.
LONG_PRESSED_REPEAT: Triggered repeatedly during a long press (used for continuous operations such as volume adjustment).
CLICKED: General click event (includes single/multiple clicks, need to combine with other events to determine the specific type).
RELEASED: Triggered when an object is released (lifted after pressing).
### Scroll and swipe events
SCROLL_BEGIN: Triggered when scrolling starts.
SCROLL_THROW_BEGIN: Triggered when a fling action starts (e.g., quickly swiping a list and releasing, causing the list to continue scrolling).
SCROLL_END: Triggered when scrolling (including inertial scrolling from a fling) ends.
SCROLL: Triggered continuously during scrolling (can get real-time scroll position).
### Gesture and input events
GESTURE: Triggered when a gesture is detected (such as swipe, pinch, rotate, etc.).
KEY: Triggered when a keyboard or key input is received (e.g., pressing/releasing a key).
ROTARY: Triggered when a rotary encoder (such as a knob) input is received (used for adjusting values).
### Focus and hover events
FOCUSED: Triggered when an object gains focus (e.g., selected via keyboard navigation).
DEFOCUSED: Triggered when an object loses focus.
HOVER_OVER: Triggered when a pointer (e.g., mouse) hovers over an object.
HOVER_LEAVE: Triggered when a pointer moves away from an object.
LEAVE: Triggered when an input device (e.g., touch) leaves the object area (similar to PRESS_LOST but not dependent on the pressed state).
### Drawing and rendering events
DRAW_MAIN_BEGIN: Triggered before the main drawing phase starts.
DRAW_MAIN: Triggered during the main drawing phase (used for custom drawing logic).
DRAW_MAIN_END: Triggered after the main drawing phase ends.
DRAW_POST_BEGIN: Triggered before the post-drawing phase starts (used for overlay drawing).
DRAW_POST: Triggered during the post-drawing phase.
DRAW_POST_END: Triggered after the post-drawing phase ends.
DRAW_TASK_ADDED: Triggered when a new drawing task is added.
REFR_EXT_DRAW_SIZE: Triggered when getting the size of the object's external drawing area (used for drawing shadows, borders, etc., beyond the object's range).
### Refresh and rendering process events
REFR_REQUEST: Triggered when a screen refresh is requested.
REFR_START: Triggered when screen refresh starts.
REFR_READY: Triggered when refresh data is ready.
RENDER_START: Triggered when rendering starts.
RENDER_READY: Triggered when rendering is complete and ready for output.
FLUSH_START: Triggered when starting to flush rendered data to the display device.
FLUSH_FINISH: Triggered when data flushing to the display device is complete.
FLUSH_WAIT_START: Triggered when starting to wait for flush completion.
FLUSH_WAIT_FINISH: Triggered when finishing waiting for flush completion.
VSYNC: Triggered when a vertical synchronization signal arrives (used for synchronizing rendering frame rate).
VSYNC_REQUEST: Triggered when requesting a vertical synchronization signal.
### Object state and lifecycle events
CREATE: Triggered when an object is created.
DELETE: Triggered when an object is deleted.
MARKED_DELETING: Triggered when an object is marked for deletion.
CHILD_CHANGED: Triggered when an object's child objects change (added/removed).
CHILD_CREATED: Triggered when a child object is created.
CHILD_DELETED: Triggered when a child object is deleted.
SIZE_CHANGED: Triggered when an object's size changes.
STYLE_CHANGED: Triggered when an object's style (such as color, font) changes.
LAYOUT_CHANGED: Triggered when an object's layout (such as position, arrangement) changes.
GET_SELF_SIZE: Triggered when getting an object's own size (excluding child objects) (used for custom layout calculations).
INVALIDATE_AREA: Triggered when an area of an object needs to be redrawn.
### Screen switching events
SCREEN_LOAD_START: Triggered when a screen starts loading.
SCREEN_LOADED: Triggered when a screen finishes loading.
SCREEN_UNLOAD_START: Triggered when a screen starts unloading.
SCREEN_UNLOADED: Triggered when a screen finishes unloading.
### Other general events
ALL: Represents all events (used for registering to listen to all events).
VALUE_CHANGED: Triggered when an object's value changes (such as slider, checkbox state changes).
INSERT: Triggered when inserting an element into a container (such as adding an item to a list).
REFRESH: Triggered when an object needs to be refreshed (force update display).
READY: Triggered when an object is ready (such as when initialization is complete).
CANCEL: Triggered when an operation is canceled (such as a dialog's cancel button).
HIT_TEST: Triggered when detecting if input hits an object (used for custom click areas).
INDEV_RESET: Triggered when an input device is reset.
COVER_CHECK: Triggered when checking if an object is covered by other objects.
RESOLUTION_CHANGED: Triggered when the screen resolution changes.
COLOR_FORMAT_CHANGED: Triggered when the screen color format changes.
PREPROCESS: Triggered during event preprocessing (used for custom event filtering).
LAST: A placeholder for event types, representing the last event (used for internal enumeration definitions).
'''
Example: Using Events
# Interaction callback function
def btn_event_cb(e):
print("Button clicked!")
# Register interaction callback function. For more states, see the "class EVENT" section in api.py
btn.add_event_cb(btn_event_cb, lv.EVENT.PRESSED, None)
4. Widget Introduction
Note: The display effect images in this chapter are online simulation images; the actual screen display color and size may vary.
4.1 Basic Object
The following code creates an object named "obj", sets its coordinates and dimensions, and adjusts its style.
- For more APIs, refer to the "class obj" section in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create an object
obj = lv.obj(scr)
# Set the object's position and size
obj.set_pos(100, 100) # Set the top-left coordinates of the object
obj.set_size(100, 100) # Set the width and height of the object
# Create a style
style_obj = lv.style_t()
# Border and background
style_obj.set_pad_all(10) # Set padding for all four directions
#style_obj.set_pad_left(10) # Set left padding
#style_obj.set_pad_right(10) # Set right padding
#style_obj.set_pad_top(10) # Set top padding
#style_obj.set_pad_bottom(10) # Set bottom padding
style_obj.set_bg_opa(255) # Set background opacity (0 = fully transparent)
style_obj.set_bg_color(lv.color_hex(0xFF0000)) # Set background color
style_obj.set_border_color(lv.color_hex(0x00FF00)) # Set border color
style_obj.set_border_width(2) # Set border width
style_obj.set_border_opa(255) # Set border opacity (0 = fully transparent)
# Shadow style
style_obj.set_shadow_color(lv.color_hex(0x00FF00))# Set shadow color
style_obj.set_shadow_width(10)# Set shadow width (shadow spread range)
style_obj.set_shadow_opa(50)# Set shadow opacity
style_obj.set_shadow_offset_x(10)# Set shadow horizontal offset
style_obj.set_shadow_offset_y(10)# Set shadow vertical offset
# Apply the style
obj.add_style(style_obj, lv.STATE.DEFAULT)
Display Effect

4.2 Label
The following code creates a label object named "label", sets its display content and position, and adjusts its style.
- For more APIs, refer to the "class label" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a label
label = lv.label(scr)
# Set long text display mode. For more parameters, see the "class LONG_MODE" section in api.py
label.set_long_mode(label.LONG_MODE.SCROLL_CIRCULAR)
# Set the display width and height of the label
label.set_size(100, 20)
# Set the label content
label.set_text('HELLO MicroPython LVGL')
# Align the label to the center of the container and offset upward by 50. For more parameters, see the "class ALIGN" section in api.py
label.align(lv.ALIGN.CENTER, 0, -50)
## Create a style. For more APIs, see the "class style_t" section in api.py
style_label = lv.style_t()
# Text color
style_label.set_text_color(lv.color_hex(0xFF0000))
# Set font (supports 12, 14, 16)
style_label.set_text_font(lv.font_montserrat_16)
# Apply as the default state style. For more states, see the "class STATE" section in api.py
label.add_style(style_label, lv.STATE.DEFAULT)
4.3 Button
- For more APIs, refer to the "class button" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a button
btn = lv.button(scr)
# Set size
btn.set_size(100, 50)
# Center the display
btn.center()
# Create a style. For more APIs, see the "class style_t" section in api.py
style_btn = lv.style_t()
# Set background color
style_btn.set_bg_color(lv.color_hex(0xFF0000))
# Apply as the pressed state style. For more states, see the "class STATE" section in api.py
btn.add_style(style_btn, lv.STATE.PRESSED)
# Interaction callback function
def btn_event_cb(e):
print("Button clicked!")
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
btn.add_event_cb(btn_event_cb, lv.EVENT.PRESSED, None)
Display Effect

4.4 Button Matrix
- For more APIs, refer to the "class buttonmatrix" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a button matrix
btnm = lv.buttonmatrix(scr)
# Set 3 buttons
btnm_map = ["A1", "A2", "A3"]
btnm.set_map(btnm_map)
# Center the display
btnm.center()
# Interaction callback function
def btnm_event_cb(e):
# Get the index of the clicked button
pressed_btn = btnm.get_selected_button()
if pressed_btn != -1:
# Get the text of the button at the corresponding index
text_btn = btnm.get_button_text(pressed_btn)
print(f"Button {text_btn} clicked")
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
btnm.add_event_cb(btnm_event_cb, lv.EVENT.CLICKED, None)
Display Effect

4.5 Switch
- For more APIs, refer to the "class switch" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a switch
switch = lv.switch(scr)
# Set size
switch.set_size(100, 50)
# Center the display
switch.center()
# Interaction callback function
def switch_event_cb(e):
if switch.has_state(lv.STATE.CHECKED):
print("Switch is ON")
else:
print("Switch is OFF")
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
switch.add_event_cb(switch_event_cb, lv.EVENT.VALUE_CHANGED, None)
Display Effect

4.6 LED
- For more APIs, refer to the "class led" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create an LED
led = lv.led(scr)
# Set size
led.set_size(50, 50)
# Set the color when lit
led.set_color(lv.color_hex(0xFF0000))
# Set brightness (range: 0-255)
led.set_brightness(150)
# Center the display
led.center()
# Turn on
#led.on()
# Turn off
#led.off()
# Toggle state
#led.toggle()
Display Effect

4.7 Checkbox
- For more APIs, refer to the "class checkbox" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a checkbox
cb = lv.checkbox(scr)
# Set checkbox text
cb.set_text("checkbox")
# Center the display
cb.center()
# Interaction callback function
def cb_event_cb(e):
if cb.has_state(lv.STATE.CHECKED):
print("Checked")
else:
print("Unchecked")
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
cb.add_event_cb(cb_event_cb, lv.EVENT.VALUE_CHANGED, None)
Display Effect

4.8 Arc
- For more APIs, refer to the "class arc" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create an arc
arc = lv.arc(scr)
# Set arc size
arc.set_size(150, 150)
# Set arc value range
arc.set_range(0, 100)
# Set current value
arc.set_value(10)
# Center the display
arc.center()
# Create a label for value display
lbl_val = lv.label(scr)
lbl_val.set_text(str(arc.get_value()))
lbl_val.align(lv.ALIGN.CENTER, 0, 0)
# Interaction callback function
def arc_event_cb(e):
current_val = arc.get_value()
lbl_val.set_text(str(current_val))
print(current_val)
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
arc.add_event_cb(arc_event_cb, lv.EVENT.VALUE_CHANGED, None)
Display Effect

4.9 Slider
- For more APIs, refer to the "class slider" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a slider
slider = lv.slider(scr)
# Set slider size
slider.set_size(300, 50)
# Set slider value range
slider.set_range(0, 100)
# Center the display
slider.center()
# Create a label for value display
lbl_val = lv.label(scr)
lbl_val.set_text(str(slider.get_value()))
lbl_val.align(lv.ALIGN.CENTER, 0, -50)
# Interaction callback function
def slider_event_cb(e):
current_val = slider.get_value()
lbl_val.set_text(str(current_val))
print(current_val)
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
slider.add_event_cb(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
Display Effect

4.10 Line
- For more APIs, refer to the "class line" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a line
line = lv.line(scr)
# Define the vertex coordinates (x, y) of the line
points = [
lv.point_precise_t({'x': 50, 'y': 50}),
lv.point_precise_t({'x': 150, 'y': 100}),
lv.point_precise_t({'x': 250, 'y': 50}),
lv.point_precise_t({'x': 300, 'y': 150})
]
# Set the vertices of the line
line.set_points(points, len(points))
4.11 Chart
- For more APIs, refer to the "class chart" and "class obj" sections in the MicroPython LVGL API.py file.
Line Chart
import screen
import lvgl as lv
import time
import random
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a line chart
chart = lv.chart(scr)
chart.set_size(300, 200) # Set chart size
chart.center() # Center the display
# Configure the chart
chart.set_type(lv.chart.TYPE.LINE) # Set to line chart type
chart.set_point_count(10) # Number of data points per series
chart.set_update_mode(lv.chart.UPDATE_MODE.SHIFT) # Data update mode: shift
chart.set_div_line_count(3, 3) # Set number of grid lines
# Set axis range
chart.set_axis_range(lv.chart.AXIS.PRIMARY_Y, 0, 100)
chart.set_axis_range(lv.chart.AXIS.PRIMARY_X, 0, 10)
# Add data series (lines)
ser1 = chart.add_series(lv.color_hex(0xFF0000), lv.chart.AXIS.PRIMARY_Y) # Red line
ser2 = chart.add_series(lv.color_hex(0x0000FF), lv.chart.AXIS.PRIMARY_Y) # Blue line
# Initialize data
chart.set_all_values(ser1, 0)
chart.set_all_values(ser2, 0)
# Simulate real-time data update
while True:
# Generate random data and add to the series
val1 = random.randint(20, 80)
val2 = random.randint(10, 90)
chart.set_next_value(ser1, val1)
chart.set_next_value(ser2, val2)
time.sleep_ms(500)
Bar Chart
import screen
import lvgl as lv
import time
import random
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a line chart (Note: The comment here is a typo; it should be "bar chart")
chart = lv.chart(scr)
chart.set_size(300, 220) # Set chart size
chart.center() # Center the display
# Configure the chart as bar chart type
chart.set_type(lv.chart.TYPE.BAR)
# Set number of data points (number of bars)
chart.set_point_count(6)
# Set grid lines: 3 horizontal lines, 2 vertical lines
chart.set_div_line_count(3, 2)
# Set Y-axis range (data value range)
chart.set_axis_range(lv.chart.AXIS.PRIMARY_Y, 0, 100)
# Add two data series (two groups of bars)
# Group 1: Red bars, using primary Y-axis
ser1 = chart.add_series(lv.color_hex(0xFF5733), lv.chart.AXIS.PRIMARY_Y)
# Group 2: Blue bars, using primary Y-axis
ser2 = chart.add_series(lv.color_hex(0x3377FF), lv.chart.AXIS.PRIMARY_Y)
# Set data for Group 1
data1 = [30, 45, 28, 67, 50, 75]
chart.set_series_values(ser1, data1, len(data1))
# Set data for Group 2
data2 = [20, 55, 38, 47, 60, 55]
chart.set_series_values(ser2, data2, len(data2))
4.12 Calendar
- For more APIs, refer to the "class calendar" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a calendar object
calendar = lv.calendar(scr)
# Set size
calendar.set_size(250, 250)
# Center the display
calendar.center()
# Set today's date (October 15, 2023)
calendar.set_today_date(2023, 10, 15)
# Set the currently displayed month
shown_date = lv.calendar_date_t()
shown_date.year = 2023
shown_date.month = 10
# Add header arrows (for switching months)
calendar.add_header_arrow()
# Add header dropdown (for selecting year and month)
calendar.add_header_dropdown()
# Set year list (2020-2030)
year_list = "\n".join([str(y) for y in range(2020, 2031)])
calendar.header_dropdown_set_year_list(year_list)
4.13 Text Area
- For more APIs, refer to the "class textarea" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a regular text area (multi-line input)
textarea1 = lv.textarea(scr)
textarea1.set_size(lv.pct(90), 100)
textarea1.set_pos(lv.pct(5), lv.pct(5))
textarea1.set_placeholder_text("Multi-line input...")
textarea1.set_max_length(100) # Maximum 100 characters
# Create a password input area
password_area = lv.textarea(scr)
password_area.set_size(lv.pct(90), 50)
password_area.set_pos(lv.pct(5), lv.pct(35))
password_area.set_placeholder_text("Please enter the password.")
password_area.set_password_mode(True)
password_area.set_password_bullet("•") # Display password as dots
password_area.set_password_show_time(1000) # Entered characters show for 1 second before turning to dots
password_area.set_max_length(20) # Maximum 20 characters for password
# Create a text area with input restriction (numbers only)
number_area = lv.textarea(scr)
number_area.set_size(lv.pct(90), 50)
number_area.set_pos(lv.pct(5), lv.pct(55))
number_area.set_placeholder_text("Please enter a number")
number_area.set_one_line(True) # Single-line mode
number_area.set_accepted_chars("0123456789") # Only numbers allowed
number_area.set_max_length(10) # Maximum 10 digits
4.14 Keyboard
- For more APIs, refer to the "class keyboard" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a keyboard
keyboard = lv.keyboard(scr)
# Set size
keyboard.set_size(400, 200)
# Align to bottom center
keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0)
# Create an input target (using textarea as an example)
textarea = lv.textarea(scr)
textarea.set_size(380, 100)
textarea.align(lv.ALIGN.TOP_MID, 0, 20)
textarea.set_placeholder_text("textarea...") # Hint text
# Bind the keyboard to the input target; after binding, keyboard input is directly passed to the textarea
keyboard.set_textarea(textarea)
Display Effect

4.15 Dropdown
- For more APIs, refer to the "class dropdown" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a dropdown control
dropdown = lv.dropdown(scr)
# Center the display
dropdown.center()
# Use a newline-separated string to represent multiple options
dropdown.set_options("case 1\ncase 2\ncase 3\ncase 4")
# Interaction callback function
def dropdown_event_cd(e):
# Get the index of the currently selected option
selected_option = dropdown.get_selected()
# Get the index of the currently selected option (Note: Duplicate comment in original code)
print(f"Selected ID: {selected_option}")
# Register the interaction callback function. For more events, see the "class EVENT" section in api.py
dropdown.add_event_cb(dropdown_event_cd, lv.EVENT.VALUE_CHANGED, None)
Display Effect

4.16 Roller
- For more APIs, refer to the "class roller" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a dropdown control (Note: Comment in original code is incorrect; should be "roller")
roller_normal = lv.roller(scr)
roller_normal.set_pos(20, 20)
roller_normal.set_size(200, 150)
# Set options and normal mode
days = "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday" # Removed extra zero-width spaces from original code
roller_normal.set_options(days, roller_normal.MODE.NORMAL)
# Set number of visible rows
roller_normal.set_visible_row_count(5)
# Create an infinite-mode roller
roller_infinite = lv.roller(scr)
roller_infinite.set_pos(240, 20)
roller_infinite.set_size(200, 150)
# Set options and infinite mode (Note: Fixed "roller_normal" to "roller_infinite" for correct mode reference)
months = "January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember" # Removed extra zero-width spaces from original code
roller_infinite.set_options(months, roller_infinite.MODE.INFINITE)
# Set number of visible rows
roller_infinite.set_visible_row_count(5)
Display Effect

4.17 List
- For more APIs, refer to the "class list" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a list object
list_obj = lv.list(scr)
list_obj.set_size(300, 200)
list_obj.center()
# Add text item
list_obj.add_text("button A")
# Add button items
btnA1 = list_obj.add_button(None, "A1")
btnA2 = list_obj.add_button(None, "A2")
btnA3 = list_obj.add_button(None, "A3")
# Add text item
list_obj.add_text("button B")
# Add button items
btnB1 = list_obj.add_button(None, "B1")
btnB2 = list_obj.add_button(None, "B2")
btnB3 = list_obj.add_button(None, "B3")
Display Effect

4.18 Tab View
- For more APIs, refer to the "class tabview" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# Create a tab view
tabview = lv.tabview(scr)
# Add tabs
tab1 = tabview.add_tab("A")
tab2 = tabview.add_tab("B")
tab3 = tabview.add_tab("C")
# Add tab content
label1 = lv.label(tab1)
label1.set_text("tabview A")
label1.center()
label2 = lv.label(tab2)
label2.set_text("tabview B")
label2.center()
label3 = lv.label(tab3)
label3.set_text("tabview C")
label3.center()
Display Effect

4.19 Menu
- For more APIs, refer to the "class menu" and "class obj" sections in the MicroPython LVGL API.py file.
Note: This widget currently has some known issues.
4.20 Table
- For more APIs, refer to the "class table" and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
# 1. Create a table instance
table = lv.table(scr)
table.set_size(300, 200) # Set table size
table.align(lv.ALIGN.CENTER, 0, 0) # Center the display
# Set number of table rows and columns
table.set_row_count(4)
table.set_column_count(3)
# Set column width
table.set_column_width(0, 80)
table.set_column_width(1, 100)
# Populate table data
table.set_cell_value(0, 0, "ID")
table.set_cell_value(0, 1, "NAME")
table.set_cell_value(0, 2, "STATE")
table.set_cell_value(1, 0, "001")
table.set_cell_value(1, 1, "Device A")
table.set_cell_value(1, 2, "ON")
table.set_cell_value(2, 0, "002")
table.set_cell_value(2, 1, "Device B")
table.set_cell_value(2, 2, "OFF")
table.set_cell_value(3, 0, "003")
table.set_cell_value(3, 1, "Device C")
table.set_cell_value(3, 2, "ON")
Display Effect

4.21 Image and GIF
- For more APIs, refer to the "class image", "class gif", and "class obj" sections in the MicroPython LVGL API.py file.
import screen
import lvgl as lv
import fs_driver
fs_drv = lv.fs_drv_t()
fs_driver.fs_register(fs_drv, 'S')
# Get the currently active screen object
scr = lv.screen_active()
# Set the screen background color to black
scr.set_style_bg_color(lv.color_hex(0x000000), 0)
'''Display LVGL built-in symbols'''
# Create an image
img_symbol = lv.image(scr)
# Display LVGL built-in symbol ("home" icon). For more icons, see the "class SYMBOL" section in api.py
img_symbol.set_src(lv.SYMBOL.HOME)
# Center the display
img_symbol.align(lv.ALIGN.CENTER, 0, 0)
'''Display images from storage'''
img_symbol2 = lv.image(scr)
# Display PNG
img_symbol2.set_src('S:001.png')
# Display JPG
#img_symbol2.set_src('S:001.jpg')
img_symbol2.align(lv.ALIGN.RIGHT_MID, 0, 0) # Align to right center
'''Display GIF'''
img_symbol3 = lv.gif(scr)
img_symbol3.set_src('S:001.gif')
img_symbol3.align(lv.ALIGN.LEFT_MID, 0, 0) # Align to left center