mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
examples(micropython): add a few missing MP examples (#3672)
This commit is contained in:
parent
d5e6ffdd87
commit
29ec34be77
156
demos/keypad_encoder/lv_demo_keypad_encoder.py
Normal file
156
demos/keypad_encoder/lv_demo_keypad_encoder.py
Normal file
@ -0,0 +1,156 @@
|
||||
class KeyboardEncoder:
|
||||
def __init__(self):
|
||||
self.LV_VER_RES = lv.scr_act().get_disp().driver.ver_res
|
||||
print("vertial size: ",self.LV_VER_RES)
|
||||
self.g = lv.group_create()
|
||||
self.g.set_default()
|
||||
|
||||
cur_drv = lv.indev_t.__cast__(None)
|
||||
while True:
|
||||
cur_drv = cur_drv.get_next()
|
||||
|
||||
if not cur_drv :
|
||||
break
|
||||
if cur_drv.driver.type == lv.INDEV_TYPE.KEYPAD:
|
||||
print("Found keypad")
|
||||
cur_drv.set_group(self.g)
|
||||
if cur_drv.driver.type == lv.INDEV_TYPE.ENCODER:
|
||||
print("Found encoder")
|
||||
cur_drv.set_group(self.g)
|
||||
|
||||
self.tv = lv.tabview(lv.scr_act(), lv.DIR.TOP, lv.DPI_DEF // 3)
|
||||
|
||||
self.t1 = self.tv.add_tab("Selectors")
|
||||
self.t2 = self.tv.add_tab("Text input")
|
||||
|
||||
self.selectors_create(self.t1)
|
||||
self.text_input_create(self.t2)
|
||||
|
||||
self.msgbox_create()
|
||||
|
||||
def selectors_create(self,parent):
|
||||
parent.set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
parent.set_flex_align(lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER)
|
||||
|
||||
obj = lv.table(parent)
|
||||
obj.set_cell_value(0, 0, "00")
|
||||
obj.set_cell_value(0, 1, "01")
|
||||
obj.set_cell_value(1, 0, "10")
|
||||
obj.set_cell_value(1, 1, "11")
|
||||
obj.set_cell_value(2, 0, "20")
|
||||
obj.set_cell_value(2, 1, "21")
|
||||
obj.set_cell_value(3, 0, "30")
|
||||
obj.set_cell_value(3, 1, "31")
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.calendar(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.btnmatrix(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
obj = lv.checkbox(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS);
|
||||
|
||||
obj = lv.slider(parent)
|
||||
obj.set_range(0, 10)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.switch(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.spinbox(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.dropdown(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
obj = lv.roller(parent)
|
||||
obj.add_flag(lv.obj.FLAG.SCROLL_ON_FOCUS)
|
||||
|
||||
list = lv.list(parent)
|
||||
list.update_layout()
|
||||
if list.get_height() > parent.get_content_height() :
|
||||
list.set_height(parent.get_content_height())
|
||||
|
||||
list.add_btn(lv.SYMBOL.OK, "Apply")
|
||||
list.add_btn(lv.SYMBOL.CLOSE, "Close")
|
||||
list.add_btn(lv.SYMBOL.EYE_OPEN, "Show")
|
||||
list.add_btn(lv.SYMBOL.EYE_CLOSE, "Hide")
|
||||
list.add_btn(lv.SYMBOL.TRASH, "Delete")
|
||||
list.add_btn(lv.SYMBOL.COPY, "Copy")
|
||||
list.add_btn(lv.SYMBOL.PASTE, "Paste")
|
||||
|
||||
def text_input_create(self,parent) :
|
||||
|
||||
parent.set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
|
||||
ta1 = lv.textarea(parent)
|
||||
ta1.set_width(lv.pct(100))
|
||||
ta1.set_one_line(True)
|
||||
ta1.set_placeholder_text("Click with an encoder to show a keyboard")
|
||||
|
||||
ta2 = lv.textarea(parent)
|
||||
ta2.set_width(lv.pct(100))
|
||||
ta2.set_one_line(True)
|
||||
ta2.set_placeholder_text("Type something")
|
||||
|
||||
self.kb = lv.keyboard(lv.scr_act())
|
||||
self.kb.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
|
||||
ta1.add_event_cb(self.ta_event_cb, lv.EVENT.ALL, None)
|
||||
ta2.add_event_cb(self.ta_event_cb, lv.EVENT.ALL, None)
|
||||
|
||||
|
||||
def msgbox_create(self):
|
||||
|
||||
btns = ["Ok", "Cancel", ""]
|
||||
mbox = lv.msgbox(None, "Hi", "Welcome to the keyboard and encoder demo", btns, False)
|
||||
mbox.add_event_cb(self.msgbox_event_cb, lv.EVENT.ALL, None)
|
||||
lv.group_focus_obj(mbox.get_btns())
|
||||
mbox.get_btns().add_state(lv.STATE.FOCUS_KEY)
|
||||
self.g.focus_freeze(True)
|
||||
|
||||
mbox.align(lv.ALIGN.CENTER, 0, 0)
|
||||
|
||||
bg = mbox.get_parent()
|
||||
bg.set_style_bg_opa(lv.OPA._70, 0)
|
||||
bg.set_style_bg_color(lv.palette_main(lv.PALETTE.GREY), 0)
|
||||
|
||||
|
||||
def msgbox_event_cb(self,e):
|
||||
|
||||
code = e.get_code();
|
||||
msgbox = e.get_current_target()
|
||||
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
txt = msgbox.get_active_btn_text()
|
||||
if txt:
|
||||
msgbox.close()
|
||||
self.g.focus_freeze(False)
|
||||
lv.group_focus_obj(self.t1.get_child(0))
|
||||
self.t1.scroll_to(0, 0, lv.ANIM.OFF)
|
||||
|
||||
def ta_event_cb(self,e) :
|
||||
|
||||
indev = lv.indev_get_act()
|
||||
if indev == None :
|
||||
return
|
||||
indev_type = indev.get_type()
|
||||
|
||||
code = e.get_code()
|
||||
ta = e.get_target()
|
||||
|
||||
if code == lv.EVENT.CLICKED and indev_type == lv.INDEV_TYPE.ENCODER:
|
||||
self.kb.set_textarea(ta)
|
||||
self.kb.clear_flag(lv.obj.FLAG.HIDDEN)
|
||||
self.kb.group_focus_obj()
|
||||
self.kb.get_group().set_editing()
|
||||
self.tv.set_height(LV_VER_RES // 2)
|
||||
lv_obj_align(kb, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
|
||||
if code == lv.EVENT.READY or code == lv.EVENT.CANCEL:
|
||||
self.kb.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
self.tv.set_height(self.LV_VER_RES)
|
||||
|
||||
|
||||
keyboard_encoder = KeyboardEncoder()
|
BIN
examples/assets/emoji/F617.png
Normal file
BIN
examples/assets/emoji/F617.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
52
examples/event/lv_example_event_4.py
Normal file
52
examples/event/lv_example_event_4.py
Normal file
@ -0,0 +1,52 @@
|
||||
class LV_Example_Event_4:
|
||||
|
||||
def __init__(self):
|
||||
#
|
||||
# Demonstrate the usage of draw event
|
||||
#
|
||||
self.size = 0
|
||||
self.size_dec = False
|
||||
self.cont = lv.obj(lv.scr_act())
|
||||
self.cont.set_size(200, 200)
|
||||
self.cont.center()
|
||||
self.cont.add_event_cb(self.event_cb, lv.EVENT.DRAW_PART_END, None)
|
||||
lv.timer_create(self.timer_cb, 30, None)
|
||||
|
||||
def timer_cb(self,timer) :
|
||||
self.cont.invalidate()
|
||||
if self.size_dec :
|
||||
self.size -= 1
|
||||
else :
|
||||
self.size += 1
|
||||
|
||||
if self.size == 50 :
|
||||
self.size_dec = True
|
||||
elif self.size == 0:
|
||||
self.size_dec = False
|
||||
|
||||
def event_cb(self,e) :
|
||||
obj = e.get_target()
|
||||
dsc = e.get_draw_part_dsc()
|
||||
if dsc.class_p == lv.obj_class and dsc.part == lv.PART.MAIN :
|
||||
draw_dsc = lv.draw_rect_dsc_t()
|
||||
draw_dsc.init()
|
||||
draw_dsc.bg_color = lv.color_hex(0xffaaaa)
|
||||
draw_dsc.radius = lv.RADIUS_CIRCLE
|
||||
draw_dsc.border_color = lv.color_hex(0xff5555)
|
||||
draw_dsc.border_width = 2
|
||||
draw_dsc.outline_color = lv.color_hex(0xff0000)
|
||||
draw_dsc.outline_pad = 3
|
||||
draw_dsc.outline_width = 2
|
||||
|
||||
a = lv.area_t()
|
||||
a.x1 = 0
|
||||
a.y1 = 0
|
||||
a.x2 = self.size
|
||||
a.y2 = self.size
|
||||
coords = lv.area_t()
|
||||
obj.get_coords(coords)
|
||||
coords.align(a, lv.ALIGN.CENTER, 0, 0)
|
||||
|
||||
dsc.draw_ctx.rect(draw_dsc, a)
|
||||
|
||||
lv_example_event_4 = LV_Example_Event_4()
|
63
examples/others/gridnav/lv_example_gridnav_1.py
Normal file
63
examples/others/gridnav/lv_example_gridnav_1.py
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Demonstrate a a basic grid navigation
|
||||
#
|
||||
# It's assumed that the default group is set and
|
||||
# there is a keyboard indev
|
||||
|
||||
cont1 = lv.obj(lv.scr_act())
|
||||
lv.gridnav_add(cont1, lv.GRIDNAV_CTRL.NONE)
|
||||
|
||||
# Use flex here, but works with grid or manually placed objects as well
|
||||
cont1.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
|
||||
cont1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
|
||||
cont1.set_size(lv.pct(50), lv.pct(100))
|
||||
|
||||
# Only the container needs to be in a group
|
||||
lv.group_get_default().add_obj(cont1)
|
||||
|
||||
label = lv.label(cont1)
|
||||
label.set_text("No rollover")
|
||||
|
||||
for i in range(10):
|
||||
obj = lv.btn(cont1)
|
||||
obj.set_size(70, lv.SIZE_CONTENT)
|
||||
obj.add_flag(lv.obj.FLAG.CHECKABLE)
|
||||
lv.group_remove_obj(obj) # Not needed, we use the gridnav instead
|
||||
|
||||
label = lv.label(obj)
|
||||
label.set_text("{:d}".format(i))
|
||||
label.center()
|
||||
|
||||
# Create a second container with rollover grid nav mode.
|
||||
|
||||
cont2 = lv.obj(lv.scr_act())
|
||||
lv.gridnav_add(cont2,lv.GRIDNAV_CTRL.ROLLOVER)
|
||||
cont2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
|
||||
cont2.set_size(lv.pct(50), lv.pct(100))
|
||||
cont2.align(lv.ALIGN.RIGHT_MID, 0, 0)
|
||||
|
||||
label = lv.label(cont2)
|
||||
label.set_width(lv.pct(100))
|
||||
label.set_text("Rollover\nUse tab to focus the other container")
|
||||
|
||||
# Only the container needs to be in a group
|
||||
lv.group_get_default().add_obj(cont2)
|
||||
|
||||
# Add and place some children manually
|
||||
ta = lv.textarea(cont2)
|
||||
ta.set_size(lv.pct(100), 80)
|
||||
ta.set_pos(0, 80);
|
||||
lv.group_remove_obj(ta) # Not needed, we use the gridnav instead
|
||||
|
||||
cb = lv.checkbox(cont2)
|
||||
cb.set_pos(0, 170)
|
||||
lv.group_remove_obj(cb) # Not needed, we use the gridnav instead
|
||||
|
||||
sw1 = lv.switch(cont2)
|
||||
sw1.set_pos(0, 200);
|
||||
lv.group_remove_obj(sw1) # Not needed, we use the gridnav instead
|
||||
|
||||
sw2 = lv.switch(cont2)
|
||||
sw2.set_pos(lv.pct(50), 200)
|
||||
lv.group_remove_obj(sw2) # Not needed, we use the gridnav instead
|
||||
|
32
examples/others/gridnav/lv_example_gridnav_2.py
Normal file
32
examples/others/gridnav/lv_example_gridnav_2.py
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Grid navigation on a list
|
||||
#
|
||||
# It's assumed that the default group is set and
|
||||
# there is a keyboard indev
|
||||
|
||||
list1 = lv.list(lv.scr_act())
|
||||
lv.gridnav_add(list1, lv.GRIDNAV_CTRL.NONE)
|
||||
list1.set_size(lv.pct(45), lv.pct(80))
|
||||
list1.align(lv.ALIGN.LEFT_MID, 5, 0)
|
||||
list1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
|
||||
lv.group_get_default().add_obj(list1)
|
||||
|
||||
for i in range(15):
|
||||
item_text = "File {:d}".format(i)
|
||||
item = list1.add_btn(lv.SYMBOL.FILE, item_text)
|
||||
item.set_style_bg_opa(0, 0)
|
||||
lv.group_remove_obj(item) # Not needed, we use the gridnav instead
|
||||
|
||||
list2 = lv.list(lv.scr_act())
|
||||
lv.gridnav_add(list2, lv.GRIDNAV_CTRL.ROLLOVER)
|
||||
list2.set_size(lv.pct(45), lv.pct(80))
|
||||
list2.align(lv.ALIGN.RIGHT_MID, -5, 0)
|
||||
list2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
|
||||
lv.group_get_default().add_obj(list2)
|
||||
|
||||
for i in range(15):
|
||||
item_text = "Folder {:d}".format(i)
|
||||
item = list2.add_btn(lv.SYMBOL.DIRECTORY, item_text)
|
||||
item.set_style_bg_opa(0, 0)
|
||||
lv.group_remove_obj(item)
|
||||
|
84
examples/others/gridnav/lv_example_gridnav_3.py
Normal file
84
examples/others/gridnav/lv_example_gridnav_3.py
Normal file
@ -0,0 +1,84 @@
|
||||
def cont_sub_event_cb(e):
|
||||
k = e.get_key()
|
||||
obj = e.get_current_target()
|
||||
if k == lv.KEY.ENTER:
|
||||
lv.group_focus_obj(obj)
|
||||
|
||||
elif k == lv.KEY.ESC:
|
||||
obj.get_group().focus_next()
|
||||
|
||||
#
|
||||
# Nested grid navigations
|
||||
#
|
||||
# It's assumed that the default group is set and
|
||||
# there is a keyboard indev*/
|
||||
|
||||
cont_main = lv.obj(lv.scr_act())
|
||||
lv.gridnav_add(cont_main,lv.GRIDNAV_CTRL.ROLLOVER | lv.GRIDNAV_CTRL.SCROLL_FIRST)
|
||||
|
||||
# Only the container needs to be in a group
|
||||
lv.group_get_default().add_obj(cont_main)
|
||||
|
||||
# Use flex here, but works with grid or manually placed objects as well
|
||||
cont_main.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
|
||||
cont_main.set_style_bg_color(lv.palette_lighten(lv.PALETTE.BLUE, 5), lv.STATE.FOCUSED)
|
||||
cont_main.set_size(lv.pct(80), lv.SIZE_CONTENT)
|
||||
|
||||
btn = lv.btn(cont_main)
|
||||
lv.group_remove_obj(btn)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button 1")
|
||||
|
||||
btn = lv.btn(cont_main)
|
||||
lv.group_remove_obj(btn)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button 2");
|
||||
|
||||
|
||||
# Create an other container with long text to show how LV_GRIDNAV_CTRL_SCROLL_FIRST works
|
||||
cont_sub1 = lv.obj(cont_main)
|
||||
cont_sub1.set_size(lv.pct(100), 100)
|
||||
|
||||
label = lv.label(cont_sub1)
|
||||
cont_sub1.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 5), lv.STATE.FOCUSED)
|
||||
label.set_width(lv.pct(100));
|
||||
label.set_text(
|
||||
"""I'm a very long text which makes my container scrollable.
|
||||
As LV_GRIDNAV_FLAG_SCROLL_FIRST is enabled arrows will scroll me first
|
||||
and a new objects will be focused only when an edge is reached with the scrolling.\n
|
||||
This is only some placeholder text to be sure the parent will be scrollable. \n
|
||||
Hello world!
|
||||
Hello world!
|
||||
Hello world!
|
||||
Hello world!
|
||||
Hello world!
|
||||
Hello world!
|
||||
""")
|
||||
|
||||
# Create a third container that can be focused with ENTER and contains an other grid nav
|
||||
cont_sub2 = lv.obj(cont_main)
|
||||
lv.gridnav_add(cont_sub2, lv.GRIDNAV_CTRL.ROLLOVER)
|
||||
#Only the container needs to be in a group
|
||||
lv.group_get_default().add_obj(cont_sub2)
|
||||
|
||||
cont_sub2.add_event_cb(cont_sub_event_cb, lv.EVENT.KEY, None)
|
||||
|
||||
# Use flex here, but works with grid or manually placed objects as well
|
||||
cont_sub2.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP)
|
||||
cont_sub2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 5), lv.STATE.FOCUSED)
|
||||
cont_sub2.set_size(lv.pct(100), lv.SIZE_CONTENT)
|
||||
|
||||
label = lv.label(cont_sub2)
|
||||
label.set_text("Use ENTER/ESC to focus/defocus this container")
|
||||
label.set_width(lv.pct(100))
|
||||
|
||||
btn = lv.btn(cont_sub2)
|
||||
lv.group_remove_obj(btn)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button 3")
|
||||
|
||||
btn = lv.btn(cont_sub2)
|
||||
lv.group_remove_obj(btn)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button 4")
|
||||
|
36
examples/others/gridnav/lv_example_gridnav_4.py
Normal file
36
examples/others/gridnav/lv_example_gridnav_4.py
Normal file
@ -0,0 +1,36 @@
|
||||
def event_handler(e):
|
||||
obj = e.get_target()
|
||||
list = obj.get_parent()
|
||||
print("Clicked: " + list.get_btn_text(obj))
|
||||
|
||||
|
||||
#
|
||||
# Simple navigation on a list widget
|
||||
#
|
||||
# It's assumed that the default group is set and
|
||||
# there is a keyboard indev
|
||||
|
||||
list = lv.list(lv.scr_act())
|
||||
lv.gridnav_add(list, lv.GRIDNAV_CTRL.ROLLOVER)
|
||||
list.align(lv.ALIGN.LEFT_MID, 0, 10)
|
||||
lv.group_get_default().add_obj(list)
|
||||
|
||||
for i in range(20):
|
||||
|
||||
# Add some separators too, they are not focusable by gridnav
|
||||
if i % 5 == 0:
|
||||
txt = "Section {:d}".format(i // 5 + 1)
|
||||
# lv_snprintf(buf, sizeof(buf), "Section %d", i / 5 + 1);
|
||||
list.add_text(txt)
|
||||
|
||||
txt = "File {:d}".format(i + 1)
|
||||
#lv_snprintf(buf, sizeof(buf), "File %d", i + 1);
|
||||
item = list.add_btn(lv.SYMBOL.FILE, txt)
|
||||
item.add_event_cb(event_handler, lv.EVENT.CLICKED, None)
|
||||
lv.group_remove_obj(item) # The default group adds it automatically
|
||||
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.align(lv.ALIGN.RIGHT_MID, 0, -10)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
|
50
examples/others/ime/lv_example_ime_pinyin_1.py
Normal file
50
examples/others/ime/lv_example_ime_pinyin_1.py
Normal file
@ -0,0 +1,50 @@
|
||||
import fs_driver
|
||||
|
||||
def ta_event_cb(e,kb):
|
||||
code = e.get_code()
|
||||
ta = e.get_target()
|
||||
|
||||
if code == lv.EVENT.FOCUSED:
|
||||
if lv.indev_get_act() != None and lv.indev_get_act().get_type() != lv.INDEV_TYPE.KEYPAD :
|
||||
kb.set_textarea(ta)
|
||||
kb.clear_flag(lv.obj.FLAG.HIDDEN)
|
||||
elif code == lv.EVENT.CANCEL:
|
||||
kb.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
ta.clear_state(ta, LV_STATE_FOCUSED);
|
||||
lv.indev_reset(None, ta) # To forget the last clicked object to make it focusable again
|
||||
|
||||
fs_drv = lv.fs_drv_t()
|
||||
fs_driver.fs_register(fs_drv, 'S')
|
||||
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
|
||||
if font_simsun_16_cjk == None:
|
||||
print("Error when loading chinese font")
|
||||
|
||||
pinyin_ime = lv.ime_pinyin(lv.scr_act())
|
||||
pinyin_ime.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
# pinyin_ime.pinyin_set_dict(your_dict) # Use a custom dictionary. If it is not set, the built-in dictionary will be used.
|
||||
|
||||
# ta1
|
||||
ta1 = lv.textarea(lv.scr_act())
|
||||
ta1.set_one_line(True)
|
||||
ta1.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
ta1.align(lv.ALIGN.TOP_LEFT, 0, 0)
|
||||
|
||||
# Create a keyboard and add it to ime_pinyin
|
||||
kb = lv.keyboard(lv.scr_act())
|
||||
pinyin_ime.pinyin_set_keyboard(kb)
|
||||
kb.set_textarea(ta1)
|
||||
|
||||
ta1.add_event_cb(lambda evt: ta_event_cb(evt,kb), lv.EVENT.ALL, None)
|
||||
|
||||
# Get the cand_panel, and adjust its size and position
|
||||
cand_panel = pinyin_ime.pinyin_get_cand_panel()
|
||||
cand_panel.set_size(lv.pct(100), lv.pct(10))
|
||||
cand_panel.align_to(kb, lv.ALIGN.OUT_TOP_MID, 0, 0)
|
||||
|
||||
# Try using ime_pinyin to output the Chinese below in the ta1 above
|
||||
cz_label = lv.label(lv.scr_act())
|
||||
cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
|
||||
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
cz_label.set_width(310)
|
||||
cz_label.align_to(ta1, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 0)
|
||||
|
52
examples/others/ime/lv_example_ime_pinyin_2.py
Normal file
52
examples/others/ime/lv_example_ime_pinyin_2.py
Normal file
@ -0,0 +1,52 @@
|
||||
import fs_driver
|
||||
|
||||
def ta_event_cb(e,kb):
|
||||
code = e.get_code()
|
||||
ta = e.get_target()
|
||||
|
||||
if code == lv.EVENT.FOCUSED:
|
||||
if lv.indev_get_act() != None and lv.indev_get_act().get_type() != lv.INDEV_TYPE.KEYPAD :
|
||||
kb.set_textarea(ta)
|
||||
kb.clear_flag(lv.obj.FLAG.HIDDEN)
|
||||
elif code == lv.EVENT.READY:
|
||||
kb.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
ta.clear_state(ta, LV_STATE_FOCUSED);
|
||||
lv.indev_reset(None, ta) # To forget the last clicked object to make it focusable again
|
||||
|
||||
fs_drv = lv.fs_drv_t()
|
||||
fs_driver.fs_register(fs_drv, 'S')
|
||||
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
|
||||
if font_simsun_16_cjk == None:
|
||||
print("Error when loading chinese font")
|
||||
|
||||
pinyin_ime = lv.ime_pinyin(lv.scr_act())
|
||||
pinyin_ime.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
# pinyin_ime.pinyin_set_dict(your_dict) # Use a custom dictionary. If it is not set, the built-in dictionary will be used.
|
||||
|
||||
# ta1
|
||||
ta1 = lv.textarea(lv.scr_act())
|
||||
ta1.set_one_line(True)
|
||||
ta1.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
ta1.align(lv.ALIGN.TOP_LEFT, 0, 0)
|
||||
|
||||
# Create a keyboard and add it to ime_pinyin
|
||||
kb = lv.keyboard(lv.scr_act())
|
||||
kb.set_textarea(ta1)
|
||||
|
||||
pinyin_ime.pinyin_set_keyboard(kb)
|
||||
pinyin_ime.pinyin_set_mode(lv.ime_pinyin.PINYIN_MODE.K9) # Set to 9-key input mode. Default: 26-key input(k26) mode.
|
||||
|
||||
ta1.add_event_cb(lambda evt: ta_event_cb(evt,kb), lv.EVENT.ALL, None)
|
||||
|
||||
# Get the cand_panel, and adjust its size and position
|
||||
cand_panel = pinyin_ime.pinyin_get_cand_panel()
|
||||
cand_panel.set_size(lv.pct(100), lv.pct(10))
|
||||
cand_panel.align_to(kb, lv.ALIGN.OUT_TOP_MID, 0, 0)
|
||||
|
||||
# Try using ime_pinyin to output the Chinese below in the ta1 above
|
||||
cz_label = lv.label(lv.scr_act())
|
||||
cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
|
||||
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
cz_label.set_width(310)
|
||||
cz_label.align_to(ta1, lv.ALIGN.OUT_BOTTOM_LEFT, 0, 0)
|
||||
|
40
examples/others/imgfont/lv_example_imgfont_1.py
Normal file
40
examples/others/imgfont/lv_example_imgfont_1.py
Normal file
@ -0,0 +1,40 @@
|
||||
import fs_driver
|
||||
import sys
|
||||
|
||||
# set LV_USE_FFMPEG to True if it is enabled in lv_conf.h
|
||||
LV_USE_FFMPEG = True
|
||||
LV_FONT_DEFAULT = lv.font_montserrat_14
|
||||
|
||||
fs_drv = lv.fs_drv_t()
|
||||
fs_driver.fs_register(fs_drv, 'A')
|
||||
|
||||
# get the directory in which the script is running
|
||||
try:
|
||||
script_path = __file__[:__file__.rfind('/')] if __file__.find('/') >= 0 else '.'
|
||||
except NameError:
|
||||
script_path = ''
|
||||
|
||||
def get_imgfont_path(font, img_src, length, unicode, unicode_next,user_data) :
|
||||
if unicode < 0xf600:
|
||||
return
|
||||
if LV_USE_FFMPEG:
|
||||
path = bytes(script_path + "/../../assets/emoji/{:04X}.png".format(unicode) + "\0","ascii")
|
||||
else:
|
||||
path = bytes("A:"+ script_path + "/../../assets/emoji/{:04X}.png".format(unicode) + "\0","ascii")
|
||||
# print("image path: ",path)
|
||||
img_src.__dereference__(length)[0:len(path)] = path
|
||||
return True
|
||||
|
||||
#
|
||||
# draw img in label or span obj
|
||||
#
|
||||
imgfont = lv.imgfont_create(80, get_imgfont_path, None)
|
||||
if imgfont == None:
|
||||
print("imgfont init error")
|
||||
|
||||
imgfont.fallback = LV_FONT_DEFAULT
|
||||
|
||||
label1 = lv.label(lv.scr_act())
|
||||
label1.set_text("12\uF600\uF617AB")
|
||||
label1.set_style_text_font(imgfont, lv.PART.MAIN)
|
||||
label1.center()
|
142
examples/others/msg/lv_example_msg_2.py
Normal file
142
examples/others/msg/lv_example_msg_2.py
Normal file
@ -0,0 +1,142 @@
|
||||
from micropython import const
|
||||
|
||||
# Define a message ID
|
||||
MSG_LOGIN_ATTEMPT = const(1)
|
||||
MSG_LOG_OUT = const(2)
|
||||
MSG_LOGIN_ERROR = const(3)
|
||||
MSG_LOGIN_OK = const(4)
|
||||
|
||||
# Define the object that will be sent as msg payload
|
||||
class Message:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def message(self):
|
||||
return self.value
|
||||
|
||||
def auth_manager(m,passwd):
|
||||
payload = m.get_payload()
|
||||
pin_act = payload.__cast__().message()
|
||||
# print("pin act: ",pin_act,end="")
|
||||
# print(", pin axpected: ",passwd)
|
||||
pin_expected = passwd
|
||||
if pin_act == pin_expected:
|
||||
lv.msg_send(MSG_LOGIN_OK, None)
|
||||
else:
|
||||
lv.msg_send(MSG_LOGIN_ERROR, Message("Incorrect PIN"))
|
||||
|
||||
def textarea_event_cb(e):
|
||||
ta = e.get_target()
|
||||
code = e.get_code()
|
||||
if code == lv.EVENT.READY:
|
||||
passwd = Message(ta.get_text())
|
||||
lv.msg_send(MSG_LOGIN_ATTEMPT, passwd)
|
||||
elif code == lv.EVENT.MSG_RECEIVED:
|
||||
m = e.get_msg()
|
||||
id = m.get_id()
|
||||
if id == MSG_LOGIN_ERROR:
|
||||
# If there was an error, clean the text area
|
||||
msg = m.get_payload().__cast__()
|
||||
if len(msg.message()):
|
||||
ta.set_text("")
|
||||
elif id == MSG_LOGIN_OK:
|
||||
ta.add_state(lv.STATE.DISABLED)
|
||||
ta.clear_state(lv.STATE.FOCUSED | lv.STATE.FOCUS_KEY)
|
||||
elif id == MSG_LOG_OUT:
|
||||
ta.set_text("");
|
||||
ta.clear_state(lv.STATE.DISABLED)
|
||||
|
||||
def log_out_event_cb(e):
|
||||
code = e.get_code()
|
||||
if code == lv.EVENT.CLICKED:
|
||||
lv.msg_send(MSG_LOG_OUT, None)
|
||||
elif code == lv.EVENT.MSG_RECEIVED:
|
||||
m = e.get_msg()
|
||||
btn = e.get_target()
|
||||
id = m.get_id()
|
||||
if id == MSG_LOGIN_OK:
|
||||
btn.clear_state(lv.STATE.DISABLED)
|
||||
elif id == MSG_LOG_OUT:
|
||||
btn.add_state(lv.STATE.DISABLED)
|
||||
|
||||
def start_engine_msg_event_cb(e):
|
||||
|
||||
m = e.get_msg()
|
||||
btn = e.get_target()
|
||||
id = m.get_id()
|
||||
if id == MSG_LOGIN_OK:
|
||||
btn.clear_state(lv.STATE.DISABLED)
|
||||
elif id == MSG_LOG_OUT:
|
||||
btn.add_state(lv.STATE.DISABLED)
|
||||
|
||||
|
||||
def info_label_msg_event_cb(e):
|
||||
label = e.get_target()
|
||||
m = e.get_msg()
|
||||
id = m.get_id()
|
||||
if id == MSG_LOGIN_ERROR:
|
||||
payload = m.get_payload()
|
||||
label.set_text(payload.__cast__().message())
|
||||
label.set_style_text_color(lv.palette_main(lv.PALETTE.RED), 0)
|
||||
elif id == MSG_LOGIN_OK:
|
||||
label.set_text("Login successful")
|
||||
label.set_style_text_color(lv.palette_main(lv.PALETTE.GREEN), 0)
|
||||
elif id == MSG_LOG_OUT:
|
||||
label.set_text("Logged out")
|
||||
label.set_style_text_color(lv.palette_main(lv.PALETTE.GREY), 0)
|
||||
|
||||
def register_auth(msg_id,auth_msg):
|
||||
lv.msg_subscribe(MSG_LOGIN_ATTEMPT, lambda m: auth_msg(m,"hello"), None)
|
||||
#
|
||||
# Simple PIN login screen.
|
||||
# No global variables are used, all state changes are communicated via messages.
|
||||
|
||||
register_auth(MSG_LOGIN_ATTEMPT,auth_manager)
|
||||
# lv.msg_subscribe_obj(MSG_LOGIN_ATTEMPT, auth_manager, "Hello")
|
||||
|
||||
# Create a slider in the center of the display
|
||||
ta = lv.textarea(lv.scr_act())
|
||||
ta.set_pos(10, 10)
|
||||
ta.set_width(200)
|
||||
ta.set_one_line(True)
|
||||
ta.set_password_mode(True)
|
||||
ta.set_placeholder_text("The password is: hello")
|
||||
ta.add_event_cb(textarea_event_cb, lv.EVENT.ALL, None)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_ERROR, ta, None)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_OK, ta, None)
|
||||
lv.msg_subscribe_obj(MSG_LOG_OUT, ta, None)
|
||||
|
||||
kb = lv.keyboard(lv.scr_act())
|
||||
kb.set_textarea(ta)
|
||||
|
||||
# Create a log out button which will be active only when logged in
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.set_pos(240, 10)
|
||||
btn.add_event_cb(log_out_event_cb, lv.EVENT.ALL, None)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_OK, btn, None)
|
||||
lv.msg_subscribe_obj(MSG_LOG_OUT, btn, None)
|
||||
|
||||
label = lv.label(btn);
|
||||
label.set_text("LOG OUT")
|
||||
|
||||
# Create a label to show info
|
||||
label = lv.label(lv.scr_act());
|
||||
label.set_text("")
|
||||
label.add_event_cb(info_label_msg_event_cb, lv.EVENT.MSG_RECEIVED, None)
|
||||
label.set_pos(10, 60)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_ERROR, label, None)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_OK, label, None)
|
||||
lv.msg_subscribe_obj(MSG_LOG_OUT, label, None)
|
||||
|
||||
#Create button which will be active only when logged in
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.set_pos(10, 80)
|
||||
btn.add_event_cb(start_engine_msg_event_cb, lv.EVENT.MSG_RECEIVED, None)
|
||||
btn.add_flag(lv.obj.FLAG.CHECKABLE)
|
||||
lv.msg_subscribe_obj(MSG_LOGIN_OK, btn, None)
|
||||
lv.msg_subscribe_obj(MSG_LOG_OUT, btn, None)
|
||||
|
||||
label = lv.label(btn)
|
||||
label.set_text("START ENGINE")
|
||||
|
||||
lv.msg_send(MSG_LOG_OUT, None)
|
||||
|
122
examples/others/msg/lv_example_msg_3.py
Normal file
122
examples/others/msg/lv_example_msg_3.py
Normal file
@ -0,0 +1,122 @@
|
||||
# Define a message ID
|
||||
MSG_INC = 1
|
||||
MSG_DEC = 2
|
||||
MSG_SET = 3
|
||||
MSG_UPDATE = 4
|
||||
MSG_UPDATE_REQUEST = 5
|
||||
|
||||
# Define the object that will be sent as msg payload
|
||||
class NewValue:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __repr__(self):
|
||||
return f"{self.value} %"
|
||||
class LV_Example_Msg_2:
|
||||
|
||||
def __init__(self):
|
||||
self.value = 10
|
||||
lv.msg_subscribe(MSG_INC, self.value_handler, None)
|
||||
lv.msg_subscribe(MSG_DEC, self.value_handler, None)
|
||||
lv.msg_subscribe(MSG_SET, self.value_handler, None)
|
||||
lv.msg_subscribe(MSG_UPDATE, self.value_handler, None)
|
||||
lv.msg_subscribe(MSG_UPDATE_REQUEST, self.value_handler, None)
|
||||
|
||||
panel = lv.obj(lv.scr_act())
|
||||
panel.set_size(250, lv.SIZE_CONTENT)
|
||||
panel.center()
|
||||
panel.set_flex_flow(lv.FLEX_FLOW.ROW)
|
||||
panel.set_flex_align(lv.FLEX_ALIGN.SPACE_BETWEEN, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START)
|
||||
|
||||
# Up button
|
||||
btn = lv.btn(panel)
|
||||
btn.set_flex_grow(1)
|
||||
btn.add_event_cb(self.btn_event_cb, lv.EVENT.ALL, None)
|
||||
label = lv.label(btn)
|
||||
label.set_text(lv.SYMBOL.LEFT)
|
||||
label.center()
|
||||
|
||||
# Current value
|
||||
label = lv.label(panel)
|
||||
label.set_flex_grow(2)
|
||||
label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
|
||||
label.set_text("?")
|
||||
lv.msg_subscribe_obj(MSG_UPDATE, label, None)
|
||||
label.add_event_cb(self.label_event_cb, lv.EVENT.MSG_RECEIVED, None)
|
||||
|
||||
# Down button
|
||||
btn = lv.btn(panel)
|
||||
btn.set_flex_grow(1)
|
||||
btn.add_event_cb(self.btn_event_cb, lv.EVENT.ALL, None)
|
||||
label = lv.label(btn)
|
||||
label.set_text(lv.SYMBOL.RIGHT)
|
||||
label.center()
|
||||
|
||||
# Slider
|
||||
slider = lv.slider(panel)
|
||||
slider.set_flex_grow(1)
|
||||
slider.add_flag(lv.OBJ_FLAG_FLEX_IN_NEW_TRACK)
|
||||
slider.add_event_cb(self.slider_event_cb, lv.EVENT.ALL, None)
|
||||
lv.msg_subscribe_obj(MSG_UPDATE, slider, None)
|
||||
|
||||
|
||||
# As there are new UI elements that don't know the system's state
|
||||
# send an UPDATE REQUEST message which will trigger an UPDATE message with the current value
|
||||
lv.msg_send(MSG_UPDATE_REQUEST, None)
|
||||
|
||||
def value_handler(self,m):
|
||||
old_value = self.value
|
||||
id = m.get_id()
|
||||
if id == MSG_INC:
|
||||
if self.value < 100:
|
||||
self.value +=1
|
||||
elif id == MSG_DEC:
|
||||
if self.value > 0:
|
||||
self.value -=1
|
||||
elif id == MSG_SET:
|
||||
payload = m.get_payload()
|
||||
new_value=payload.__cast__()
|
||||
self.value = new_value.value
|
||||
# print("value_handler: new value: {:d}".format(new_value.value))
|
||||
elif id == MSG_UPDATE_REQUEST:
|
||||
lv.msg_send(MSG_UPDATE, NewValue(self.value))
|
||||
|
||||
if self.value != old_value:
|
||||
lv.msg_send(MSG_UPDATE, NewValue(self.value));
|
||||
|
||||
def btn_event_cb(self,e):
|
||||
btn = e.get_target()
|
||||
code = e.get_code()
|
||||
if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
|
||||
if btn.get_index() == 0: # rst object is the dec. button
|
||||
lv.msg_send(MSG_DEC, None)
|
||||
else :
|
||||
lv.msg_send(MSG_INC, None)
|
||||
|
||||
def label_event_cb(self,e):
|
||||
label = e.get_target()
|
||||
code = e.get_code()
|
||||
if code == lv.EVENT.MSG_RECEIVED:
|
||||
m = e.get_msg()
|
||||
if m.get_id() == MSG_UPDATE:
|
||||
payload = m.get_payload()
|
||||
value=payload.__cast__()
|
||||
# print("label_event_cb: " + str(value))
|
||||
label.set_text(str(value))
|
||||
|
||||
def slider_event_cb(self,e):
|
||||
slider = e.get_target()
|
||||
code = e.get_code()
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
v = slider.get_value()
|
||||
# print("slider_event_cb: {:d}".format(v))
|
||||
lv.msg_send(MSG_SET, NewValue(v))
|
||||
|
||||
elif code == lv.EVENT.MSG_RECEIVED:
|
||||
m = e.get_msg()
|
||||
if m.get_id() == MSG_UPDATE:
|
||||
v = m.get_payload()
|
||||
value = v.__cast__()
|
||||
slider.set_value(value.value, lv.ANIM.OFF)
|
||||
|
||||
lv_example_msg_2 = LV_Example_Msg_2()
|
||||
|
@ -1,24 +1,38 @@
|
||||
#!/opt/bin/lv_micropython -i
|
||||
import lvgl as lv
|
||||
import display_driver
|
||||
|
||||
def event_cb(e):
|
||||
|
||||
code = e.get_code()
|
||||
chart = e.get_target()
|
||||
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
chart.invalidate()
|
||||
|
||||
|
||||
if code == lv.EVENT.REFR_EXT_DRAW_SIZE:
|
||||
# s = lv.coord_t.__cast__(e.get_param())
|
||||
# print("s: {:d}".format(s))
|
||||
e.set_ext_draw_size(20)
|
||||
|
||||
|
||||
elif code == lv.EVENT.DRAW_POST_END:
|
||||
id = lv.chart.get_pressed_point(chart)
|
||||
if id == lv.CHART_POINT_NONE:
|
||||
id = chart.get_pressed_point()
|
||||
if id == lv.CHART_POINT_NONE :
|
||||
return
|
||||
# print("Selected point ", id)
|
||||
for i in range(len(series)):
|
||||
p = lv.point_t()
|
||||
chart.get_point_pos_by_id(series[i], id, p)
|
||||
value = series_points[i][id]
|
||||
buf = lv.SYMBOL.DUMMY + "$" + str(value)
|
||||
|
||||
# print("Selected point {:d}".format(id))
|
||||
|
||||
ser = chart.get_series_next(None)
|
||||
|
||||
while(ser) :
|
||||
p = lv.point_t()
|
||||
chart.get_point_pos_by_id(ser, id, p)
|
||||
# print("point coords: x: {:d}, y: {:d}".format(p.x,p.y))
|
||||
y_array = chart.get_y_array(ser)
|
||||
value = y_array[id]
|
||||
|
||||
buf = lv.SYMBOL.DUMMY + "{:2d}".format(value)
|
||||
|
||||
draw_rect_dsc = lv.draw_rect_dsc_t()
|
||||
draw_rect_dsc.init()
|
||||
draw_rect_dsc.bg_color = lv.color_black()
|
||||
@ -26,23 +40,27 @@ def event_cb(e):
|
||||
draw_rect_dsc.radius = 3
|
||||
draw_rect_dsc.bg_img_src = buf
|
||||
draw_rect_dsc.bg_img_recolor = lv.color_white()
|
||||
|
||||
a = lv.area_t()
|
||||
|
||||
coords = lv.area_t()
|
||||
chart.get_coords(coords)
|
||||
# print("coords: x1: {:d}, y1: {:d}".format(coords.x1, coords.y1))
|
||||
a = lv.area_t()
|
||||
a.x1 = coords.x1 + p.x - 20
|
||||
a.x2 = coords.x1 + p.x + 20
|
||||
a.y1 = coords.y1 + p.y - 30
|
||||
a.y2 = coords.y1 + p.y - 10
|
||||
|
||||
clip_area = lv.area_t.__cast__(e.get_param())
|
||||
lv.draw_rect(a, clip_area, draw_rect_dsc)
|
||||
# print("a: x1: {:d}, x2: {:d}, y1: {:d}, y2: {:d}".format(a.x1,a.x2,a.y1,a.y2))
|
||||
draw_ctx = e.get_draw_ctx()
|
||||
draw_ctx.rect(draw_rect_dsc, a)
|
||||
|
||||
ser = chart.get_series_next(ser)
|
||||
|
||||
elif code == lv.EVENT.RELEASED:
|
||||
chart.invalidate()
|
||||
|
||||
#
|
||||
# Add ticks and labels to the axis and demonstrate scrolling
|
||||
|
||||
#
|
||||
# Show the value of the pressed points
|
||||
#
|
||||
|
||||
# Create a chart
|
||||
@ -51,6 +69,7 @@ chart.set_size(200, 150)
|
||||
chart.center()
|
||||
|
||||
chart.add_event_cb(event_cb, lv.EVENT.ALL, None)
|
||||
|
||||
chart.refresh_ext_draw_size()
|
||||
|
||||
# Zoom in a little in X
|
||||
@ -59,15 +78,7 @@ chart.set_zoom_x(800)
|
||||
# Add two data series
|
||||
ser1 = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
|
||||
ser2 = chart.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.PRIMARY_Y)
|
||||
|
||||
ser1_p = []
|
||||
ser2_p = []
|
||||
for i in range(10):
|
||||
ser1_p.append(lv.rand(60,90))
|
||||
ser2_p.append(lv.rand(10,40))
|
||||
ser1.y_points = ser1_p
|
||||
ser2.y_points = ser2_p
|
||||
|
||||
series = [ser1,ser2]
|
||||
series_points=[ser1_p,ser2_p]
|
||||
chart.set_next_value(ser1, lv.rand(60, 90))
|
||||
chart.set_next_value(ser2, lv.rand(10, 40))
|
||||
|
||||
|
83
examples/widgets/checkbox/lv_example_checkbox_2.py
Normal file
83
examples/widgets/checkbox/lv_example_checkbox_2.py
Normal file
@ -0,0 +1,83 @@
|
||||
import time
|
||||
|
||||
class LV_Example_Checkbox_2:
|
||||
def __init__(self):
|
||||
#
|
||||
# Checkboxes as radio buttons
|
||||
#
|
||||
# The idea is to enable `LV_OBJ_FLAG_EVENT_BUBBLE` on checkboxes and process the
|
||||
#`LV.EVENT.CLICKED` on the container.
|
||||
# Since user_data cannot be used to pass parameters in MicroPython I use an instance variable to
|
||||
# keep the index of the active button
|
||||
|
||||
self.active_index_1 = 0
|
||||
self.active_index_2 = 0
|
||||
self.style_radio = lv.style_t()
|
||||
self.style_radio.init()
|
||||
self.style_radio.set_radius(lv.RADIUS_CIRCLE)
|
||||
|
||||
self.style_radio_chk = lv.style_t()
|
||||
self.style_radio_chk.init()
|
||||
self.style_radio_chk.init()
|
||||
self.style_radio_chk.set_bg_img_src(None)
|
||||
|
||||
self.cont1 = lv.obj(lv.scr_act())
|
||||
self.cont1.set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
self.cont1.set_size(lv.pct(40), lv.pct(80))
|
||||
self.cont1.add_event_cb(self.radio_event_handler, lv.EVENT.CLICKED, None)
|
||||
|
||||
for i in range(5):
|
||||
txt = "A {:d}".format(i+1)
|
||||
self.radiobutton_create(self.cont1,txt)
|
||||
|
||||
# Make the first checkbox checked
|
||||
#lv_obj_add_state(lv_obj_get_child(self.cont1, 0), LV_STATE_CHECKED);
|
||||
self.cont1.get_child(0).add_state(lv.STATE.CHECKED)
|
||||
|
||||
self.cont2 = lv.obj(lv.scr_act())
|
||||
self.cont2.set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
self.cont2.set_size(lv.pct(40), lv.pct(80))
|
||||
self.cont2.set_x(lv.pct(50))
|
||||
self.cont2.add_event_cb(self.radio_event_handler, lv.EVENT.CLICKED, None)
|
||||
|
||||
for i in range(3):
|
||||
txt = "B {:d}".format(i+1)
|
||||
self.radiobutton_create(self.cont2,txt)
|
||||
|
||||
# Make the first checkbox checked*/
|
||||
self.cont2.get_child(0).add_state(lv.STATE.CHECKED)
|
||||
|
||||
|
||||
def radio_event_handler(self,e):
|
||||
cont = e.get_current_target()
|
||||
act_cb = e.get_target()
|
||||
if cont == self.cont1:
|
||||
active_id = self.active_index_1
|
||||
else:
|
||||
active_id = self.active_index_2
|
||||
old_cb = cont.get_child(active_id)
|
||||
|
||||
# Do nothing if the container was clicked
|
||||
if act_cb == cont:
|
||||
return
|
||||
|
||||
old_cb.clear_state(lv.STATE.CHECKED) # Uncheck the previous radio button
|
||||
act_cb.add_state(lv.STATE.CHECKED) # Uncheck the current radio button
|
||||
|
||||
if cont == self.cont1:
|
||||
self.active_index_1 = act_cb.get_index()
|
||||
# print("active index 1: ", self.active_index_1)
|
||||
else:
|
||||
self.active_index_2 = act_cb.get_index()
|
||||
# print("active index 2: ", self.active_index_2)
|
||||
|
||||
print("Selected radio buttons: {:d}, {:d}".format(self.active_index_1, self.active_index_2))
|
||||
|
||||
def radiobutton_create(self,parent, txt):
|
||||
obj = lv.checkbox(parent)
|
||||
obj.set_text(txt)
|
||||
obj.add_flag(lv.obj.FLAG.EVENT_BUBBLE)
|
||||
obj.add_style(self.style_radio, lv.PART.INDICATOR)
|
||||
obj.add_style(self.style_radio_chk, lv.PART.INDICATOR | lv.STATE.CHECKED)
|
||||
|
||||
lv_example_checkbox_2 = LV_Example_Checkbox_2()
|
26
examples/widgets/keyboard/lv_example_keyboard_2.py
Normal file
26
examples/widgets/keyboard/lv_example_keyboard_2.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Create an AZERTY keyboard map
|
||||
kb_map = ["A", "Z", "E", "R", "T", "Y", "U", "I", "O", "P", lv.SYMBOL.BACKSPACE, "\n",
|
||||
"Q", "S", "D", "F", "G", "J", "K", "L", "M", lv.SYMBOL.NEW_LINE, "\n",
|
||||
"W", "X", "C", "V", "B", "N", ",", ".", ":", "!", "?", "\n",
|
||||
lv.SYMBOL.CLOSE, " ", " ", " ", lv.SYMBOL.OK, None]
|
||||
|
||||
# Set the relative width of the buttons and other controls
|
||||
kb_ctrl = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
2, lv.btnmatrix.CTRL.HIDDEN | 2, 6, lv.btnmatrix.CTRL.HIDDEN | 2, 2]
|
||||
|
||||
# Create a keyboard and add the new map as USER_1 mode
|
||||
kb = lv.keyboard(lv.scr_act())
|
||||
|
||||
kb.set_map(lv.keyboard.MODE.USER_1, kb_map, kb_ctrl)
|
||||
kb.set_mode(lv.keyboard.MODE.USER_1)
|
||||
|
||||
# Create a text area. The keyboard will write here
|
||||
ta = lv.textarea(lv.scr_act())
|
||||
ta.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||
ta.set_size(lv.pct(90), 80)
|
||||
ta.add_state(lv.STATE.FOCUSED)
|
||||
|
||||
kb.set_textarea(ta)
|
||||
|
175
examples/widgets/menu/lv_example_menu_5.py
Normal file
175
examples/widgets/menu/lv_example_menu_5.py
Normal file
@ -0,0 +1,175 @@
|
||||
from micropython import const
|
||||
|
||||
def create_text(parent, icon, txt, builder_variant):
|
||||
|
||||
obj = lv.menu_cont(parent)
|
||||
|
||||
img = None
|
||||
label = None
|
||||
|
||||
if icon :
|
||||
img = lv.img(obj)
|
||||
img.set_src(icon)
|
||||
|
||||
if txt :
|
||||
label = lv.label(obj)
|
||||
label.set_text(txt)
|
||||
label.set_long_mode(lv.label.LONG.SCROLL_CIRCULAR)
|
||||
label.set_flex_grow(1)
|
||||
|
||||
if builder_variant == LV_MENU_ITEM_BUILDER_VARIANT_2 and icon and txt :
|
||||
img.add_flag(lv.OBJ_FLAG_FLEX_IN_NEW_TRACK)
|
||||
img.swap(label)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
def create_slider(parent, icon, txt, min, max, val) :
|
||||
|
||||
obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_2)
|
||||
|
||||
slider = lv.slider(obj)
|
||||
slider.set_flex_grow(1)
|
||||
slider.set_range(min, max)
|
||||
slider.set_value(val, lv.ANIM.OFF)
|
||||
|
||||
if icon == None :
|
||||
slider.add_flag(lv.obj.FLAG_FLEX.IN_NEW_TRACK)
|
||||
|
||||
return obj
|
||||
|
||||
def create_switch(parent, icon, txt, chk) :
|
||||
|
||||
obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_1)
|
||||
|
||||
sw = lv.switch(obj)
|
||||
if chk == lv.STATE.CHECKED:
|
||||
sw.add_state(chk )
|
||||
else:
|
||||
sw.add_state(0)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
def back_event_handler(e,menu):
|
||||
|
||||
obj = e.get_target()
|
||||
# menu = lv_event_get_user_data(e);
|
||||
|
||||
if menu.back_btn_is_root(obj) :
|
||||
mbox1 = lv.msgbox(None, "Hello", "Root back btn click.", None, True)
|
||||
mbox1.center()
|
||||
|
||||
def switch_handler(e,menu):
|
||||
|
||||
code = e.get_code()
|
||||
obj = e.get_target()
|
||||
if code == lv.EVENT.VALUE_CHANGED :
|
||||
if obj.has_state(lv.STATE.CHECKED) :
|
||||
menu.set_page(None)
|
||||
menu.set_sidebar_page(root_page)
|
||||
# lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);
|
||||
lv.event_send(menu.get_cur_sidebar_page().get_child(0).get_child(0),lv.EVENT.CLICKED,None)
|
||||
else :
|
||||
menu.set_sidebar_page(None)
|
||||
menu.clear_history() # Clear history because we will be showing the root page later
|
||||
menu.set_page(root_page)
|
||||
|
||||
LV_MENU_ITEM_BUILDER_VARIANT_1 = const(0)
|
||||
LV_MENU_ITEM_BUILDER_VARIANT_2 = const(1)
|
||||
|
||||
LV_HOR_RES = lv.scr_act().get_disp().driver.hor_res
|
||||
LV_VER_RES = lv.scr_act().get_disp().driver.ver_res
|
||||
|
||||
menu = lv.menu(lv.scr_act())
|
||||
|
||||
bg_color = menu.get_style_bg_color(0)
|
||||
if bg_color.color_brightness() > 127 :
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).color_darken(10),0)
|
||||
else :
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).color_darken(50),0)
|
||||
|
||||
|
||||
menu.set_mode_root_back_btn(lv.menu.ROOT_BACK_BTN.ENABLED)
|
||||
menu.add_event_cb(lambda evt: back_event_handler(evt,menu), lv.EVENT.CLICKED, None)
|
||||
menu.set_size(LV_HOR_RES, LV_VER_RES )
|
||||
menu.center()
|
||||
|
||||
# Create sub pages
|
||||
sub_mechanics_page = lv.menu_page(menu, None)
|
||||
sub_mechanics_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
lv.menu_separator(sub_mechanics_page)
|
||||
section = lv.menu_section(sub_mechanics_page);
|
||||
create_slider(section,lv.SYMBOL.SETTINGS, "Velocity", 0, 150, 120)
|
||||
create_slider(section,lv.SYMBOL.SETTINGS, "Acceleration", 0, 150, 50)
|
||||
create_slider(section,lv.SYMBOL.SETTINGS, "Weight limit", 0, 150, 80)
|
||||
|
||||
sub_sound_page = lv.menu_page(menu, None)
|
||||
sub_sound_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
lv.menu_separator(sub_sound_page)
|
||||
section = lv.menu_section(sub_sound_page)
|
||||
create_switch(section,lv.SYMBOL.AUDIO, "Sound", False)
|
||||
|
||||
sub_display_page = lv.menu_page(menu, None)
|
||||
sub_display_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
lv.menu_separator(sub_display_page)
|
||||
section = lv.menu_section(sub_display_page)
|
||||
create_slider(section,lv.SYMBOL.SETTINGS, "Brightness", 0, 150, 100)
|
||||
|
||||
sub_software_info_page = lv.menu_page(menu, None)
|
||||
sub_software_info_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
section = lv.menu_section(sub_software_info_page)
|
||||
create_text(section,None, "Version 1.0", LV_MENU_ITEM_BUILDER_VARIANT_1)
|
||||
|
||||
sub_legal_info_page = lv.menu_page(menu, None)
|
||||
sub_legal_info_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
|
||||
section = lv.menu_section(sub_legal_info_page)
|
||||
|
||||
for i in range(15):
|
||||
create_text(section, None,
|
||||
"This is a long long long long long long long long long text, if it is long enough it may scroll.",
|
||||
LV_MENU_ITEM_BUILDER_VARIANT_1)
|
||||
|
||||
sub_about_page = lv.menu_page(menu, None)
|
||||
sub_about_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
|
||||
lv.menu_separator(sub_about_page)
|
||||
section = lv.menu_section(sub_about_page)
|
||||
cont = create_text(section, None, "Software information", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_software_info_page);
|
||||
cont = create_text(section, None, "Legal information", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_legal_info_page)
|
||||
|
||||
sub_menu_mode_page = lv.menu_page(menu, None)
|
||||
sub_menu_mode_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
lv.menu_separator(sub_menu_mode_page)
|
||||
section = lv.menu_section(sub_menu_mode_page)
|
||||
cont = create_switch(section, lv.SYMBOL.AUDIO, "Sidebar enable",True)
|
||||
cont.get_child(2).add_event_cb(lambda evt: switch_handler(evt,menu), lv.EVENT.VALUE_CHANGED, None)
|
||||
|
||||
# Create a root page
|
||||
root_page = lv.menu_page(menu, "Settings")
|
||||
root_page.set_style_pad_hor(menu.get_main_header().get_style_pad_left(0),0)
|
||||
section = lv.menu_section(root_page)
|
||||
cont = create_text(section, lv.SYMBOL.SETTINGS, "Mechanics", LV_MENU_ITEM_BUILDER_VARIANT_1)
|
||||
menu.set_load_page_event(cont, sub_mechanics_page);
|
||||
cont = create_text(section, lv.SYMBOL.AUDIO, "Sound", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_sound_page)
|
||||
cont = create_text(section, lv.SYMBOL.SETTINGS, "Display", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_display_page)
|
||||
|
||||
create_text(root_page, None, "Others", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
section = lv.menu_section(root_page)
|
||||
cont = create_text(section, None, "About", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_about_page)
|
||||
cont = create_text(section, lv.SYMBOL.SETTINGS, "Menu mode", LV_MENU_ITEM_BUILDER_VARIANT_1);
|
||||
menu.set_load_page_event(cont, sub_menu_mode_page)
|
||||
|
||||
menu.set_sidebar_page(root_page)
|
||||
|
||||
lv.event_send(menu.get_cur_sidebar_page().get_child(0).get_child(0),lv.EVENT.CLICKED,None)
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user