多功能¶
例程¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | import lvgl as lv
import lvgl_helper as lv_h
import touchscreen as ts
import lcd
import time
lcd.init()
ts.init()
lv.init()
disp_buf1 = lv.disp_buf_t()
buf1_1 = bytearray(320*10)
lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1)//4)
disp_drv = lv.disp_drv_t()
lv.disp_drv_init(disp_drv)
disp_drv.buffer = disp_buf1
disp_drv.flush_cb = lv_h.flush
disp_drv.hor_res = 320
disp_drv.ver_res = 240
lv.disp_drv_register(disp_drv)
indev_drv = lv.indev_drv_t()
lv.indev_drv_init(indev_drv)
indev_drv.type = lv.INDEV_TYPE.POINTER
indev_drv.read_cb = lv_h.read
lv.indev_drv_register(indev_drv)
class Page_Buttons:
def __init__(self, app, page):
self.app = app
self.page = page
# counter button
self.counter_btn = lv.btn(page)
self.counter_btn.set_size(100,60)
self.counter_btn.align(page, lv.ALIGN.CENTER, 0, 0)
self.counter_label = lv.label(self.counter_btn)
self.counter_label.set_text('Count')
self.counter_btn.set_event_cb(self.on_counter_btn)
self.counter = 0
def on_counter_btn(self, obj, event):
if event == lv.EVENT.CLICKED:
self.counter += 1
self.counter_label.set_text(str(self.counter))
class Page_Slider:
def __init__(self, app, page):
self.app = app
self.page = page
# slider
self.slider = lv.slider(page)
self.slider.align(page, lv.ALIGN.CENTER, 0, -10)
self.slider_label = lv.label(page)
self.slider_label.align(self.slider, lv.ALIGN.OUT_LEFT_MID, -10, 0)
self.slider.set_event_cb(self.on_slider_changed)
self.on_slider_changed(None)
def on_slider_changed(self, obj=None, event=-1):
self.slider_label.set_text(str(self.slider.get_value()))
class Anim(lv.anim_t):
def __init__(self, obj, val, size, exec_cb, path_cb, time=500, playback = False, ready_cb=None):
super().__init__()
lv.anim_init(self)
lv.anim_set_time(self, time, 0)
lv.anim_set_values(self, val, val+size)
if callable(exec_cb):
lv.anim_set_custom_exec_cb(self, exec_cb)
else:
lv.anim_set_exec_cb(self, obj, exec_cb)
lv.anim_set_path_cb(self, path_cb )
if playback: lv.anim_set_playback(self, 0)
if ready_cb: lv.anim_set_ready_cb(self, ready_cb)
lv.anim_create(self)
class AnimatedChart(lv.chart):
def __init__(self, parent, val, size):
super().__init__(parent)
self.val = val
self.size = size
self.max = 2000
self.min = 500
self.factor = 100
self.anim_phase1()
def anim_phase1(self):
Anim(
self,
self.val,
self.size,
lambda a, val: self.set_range(0, val),
lv.anim_path_ease_in,
ready_cb=lambda a:self.anim_phase2(),
time=(self.max * self.factor) // 100)
def anim_phase2(self):
Anim(
self,
self.val+self.size,
-self.size,
lambda a, val: self.set_range(0, val),
lv.anim_path_ease_out,
ready_cb=lambda a:self.anim_phase1(),
time=(self.min * self.factor) // 100)
class Page_Chart():
def __init__(self, app, page):
self.app = app
self.page = page
self.chart = AnimatedChart(page, 100, 1000)
self.chart.set_width(page.get_width() - 100)
self.chart.set_height(page.get_height() - 30)
self.chart.align(page, lv.ALIGN.CENTER, 0, 0)
self.series1 = self.chart.add_series(lv.color_hex(0xFF0000))
self.chart.set_type(self.chart.TYPE.POINT | self.chart.TYPE.LINE)
self.chart.set_series_width(3)
self.chart.set_range(0,100)
self.chart.init_points(self.series1, 10)
self.chart.set_points(self.series1, [10,20,30,20,10,40,50,80,95,80])
self.chart.set_x_tick_texts('a\nb\nc\nd\ne', 2, lv.chart.AXIS.DRAW_LAST_TICK)
self.chart.set_x_tick_length(10, 5)
self.chart.set_y_tick_texts('1\n2\n3\n4\n5', 2, lv.chart.AXIS.DRAW_LAST_TICK)
self.chart.set_y_tick_length(10, 5)
self.chart.set_div_line_count(3, 3)
self.chart.set_margin(30)
self.slider = lv.slider(page)
self.slider.align(self.chart, lv.ALIGN.OUT_RIGHT_TOP, 10, 0)
self.slider.set_width(30)
self.slider.set_height(self.chart.get_height())
self.slider.set_range(10, 200)
self.slider.set_value(self.chart.factor, 0)
self.slider.set_event_cb(self.on_slider_changed)
# Create a slider that controls the chart animation speed
def on_slider_changed(self, obj=None, event=-1):
self.chart.factor = self.slider.get_value()
class Screen_Main(lv.obj):
def __init__(self, app, *args, **kwds):
self.app = app
super().__init__(*args, **kwds)
self.tabview = lv.tabview(self)
self.tabview.set_style(lv.tabview.STYLE.BG, lv.style_plain_color)
self.page_buttons = Page_Buttons(self.app, self.tabview.add_tab('Button'))
self.page_slider = Page_Slider(self.app, self.tabview.add_tab('Slider'))
self.page_chart = Page_Chart(self.app, self.tabview.add_tab('Chart'))
screen_main = Screen_Main(lv.obj())
lv.scr_load(screen_main)
tim = time.ticks_ms()
while True:
if time.ticks_ms()-tim > 5:
tim = time.ticks_ms()
lv.task_handler()
lv.tick_inc(5)
|
实验准备¶
将
野火K210 AI视觉相机
连接到CanMV IDE
执行程序
运行结果¶
1.运行程序后,可以看到 野火K210 AI视觉相机
会显示下面内容

2.点击两下 button
按键后,可以看到 button
变成 1
再由 1
变成 2

3.按住屏幕的右边缘向左边滑动或者点击 slider
按键,切换带滑块页面

4.按住白色小方块,往右边拖,可以看到下面内容

5.按住屏幕的右边缘向左边滑动或者点击 chart
按键,切换带图表页面,此时图表里面的内容会上下运动

6.按住右边的小滑块,往上推,可以看到图表里的变化趋势变得很慢

7.按住右边的小滑块,往下拉,可以看到图表里的变化趋势变得很快

讲解¶
1 2 3 4 5 | import lvgl as lv
import lvgl_helper as lv_h
import touchscreen as ts
import lcd
import time
|
这些库提供了LVGL框架、LCD显示、触摸屏支持和一些辅助函数
1 2 3 | lcd.init()
ts.init()
lv.init()
|
这三行代码分别初始化了LCD显示、触摸屏和LVGL库。
1 2 3 4 5 6 7 8 9 10 | disp_buf1 = lv.disp_buf_t()
buf1_1 = bytearray(320*10)
lv.disp_buf_init(disp_buf1, buf1_1, None, len(buf1_1)//4)
disp_drv = lv.disp_drv_t()
lv.disp_drv_init(disp_drv)
disp_drv.buffer = disp_buf1
disp_drv.flush_cb = lv_h.flush
disp_drv.hor_res = 320
disp_drv.ver_res = 240
lv.disp_drv_register(disp_drv)
|
这些代码创建了一个显示缓冲区disp_buf1,并设置了一个显示驱动程序disp_drv,包括缓冲区、刷新回调函数、水平分辨率和垂直分辨率。
1 2 3 4 5 | indev_drv = lv.indev_drv_t()
lv.indev_drv_init(indev_drv)
indev_drv.type = lv.INDEV_TYPE.POINTER
indev_drv.read_cb = lv_h.read
lv.indev_drv_register(indev_drv)
|
这些代码创建并初始化了一个输入设备驱动程序对象indev_drv,用于处理触摸屏输入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Page_Buttons:
def __init__(self, app, page):
self.app = app
self.page = page
# counter button
self.counter_btn = lv.btn(page)
self.counter_btn.set_size(100,60)
self.counter_btn.align(page, lv.ALIGN.CENTER, 0, 0)
self.counter_label = lv.label(self.counter_btn)
self.counter_label.set_text('Count')
self.counter_btn.set_event_cb(self.on_counter_btn)
self.counter = 0
def on_counter_btn(self, obj, event):
if event == lv.EVENT.CLICKED:
self.counter += 1
self.counter_label.set_text(str(self.counter))
|
定义了按钮页面,具体可参照上面章节的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Page_Slider:
def __init__(self, app, page):
self.app = app
self.page = page
# slider
self.slider = lv.slider(page)
self.slider.align(page, lv.ALIGN.CENTER, 0, -10)
self.slider_label = lv.label(page)
self.slider_label.align(self.slider, lv.ALIGN.OUT_LEFT_MID, -10, 0)
self.slider.set_event_cb(self.on_slider_changed)
self.on_slider_changed(None)
def on_slider_changed(self, obj=None, event=-1):
self.slider_label.set_text(str(self.slider.get_value()))
|
定义了滑块页面,具体可参照上面章节的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | class Anim(lv.anim_t):
def __init__(self, obj, val, size, exec_cb, path_cb, time=500, playback = False, ready_cb=None):
super().__init__()
lv.anim_init(self)
lv.anim_set_time(self, time, 0)
lv.anim_set_values(self, val, val+size)
if callable(exec_cb):
lv.anim_set_custom_exec_cb(self, exec_cb)
else:
lv.anim_set_exec_cb(self, obj, exec_cb)
lv.anim_set_path_cb(self, path_cb )
if playback: lv.anim_set_playback(self, 0)
if ready_cb: lv.anim_set_ready_cb(self, ready_cb)
lv.anim_create(self)
class AnimatedChart(lv.chart):
def __init__(self, parent, val, size):
super().__init__(parent)
self.val = val
self.size = size
self.max = 2000
self.min = 500
self.factor = 100
self.anim_phase1()
def anim_phase1(self):
Anim(
self,
self.val,
self.size,
lambda a, val: self.set_range(0, val),
lv.anim_path_ease_in,
ready_cb=lambda a:self.anim_phase2(),
time=(self.max * self.factor) // 100)
def anim_phase2(self):
Anim(
self,
self.val+self.size,
-self.size,
lambda a, val: self.set_range(0, val),
lv.anim_path_ease_out,
ready_cb=lambda a:self.anim_phase1(),
time=(self.min * self.factor) // 100)
class Page_Chart():
def __init__(self, app, page):
self.app = app
self.page = page
self.chart = AnimatedChart(page, 100, 1000)
self.chart.set_width(page.get_width() - 100)
self.chart.set_height(page.get_height() - 30)
self.chart.align(page, lv.ALIGN.CENTER, 0, 0)
self.series1 = self.chart.add_series(lv.color_hex(0xFF0000))
self.chart.set_type(self.chart.TYPE.POINT | self.chart.TYPE.LINE)
self.chart.set_series_width(3)
self.chart.set_range(0,100)
self.chart.init_points(self.series1, 10)
self.chart.set_points(self.series1, [10,20,30,20,10,40,50,80,95,80])
self.chart.set_x_tick_texts('a\nb\nc\nd\ne', 2, lv.chart.AXIS.DRAW_LAST_TICK)
self.chart.set_x_tick_length(10, 5)
self.chart.set_y_tick_texts('1\n2\n3\n4\n5', 2, lv.chart.AXIS.DRAW_LAST_TICK)
self.chart.set_y_tick_length(10, 5)
self.chart.set_div_line_count(3, 3)
self.chart.set_margin(30)
self.slider = lv.slider(page)
self.slider.align(self.chart, lv.ALIGN.OUT_RIGHT_TOP, 10, 0)
self.slider.set_width(30)
self.slider.set_height(self.chart.get_height())
self.slider.set_range(10, 200)
self.slider.set_value(self.chart.factor, 0)
self.slider.set_event_cb(self.on_slider_changed)
# Create a slider that controls the chart animation speed
def on_slider_changed(self, obj=None, event=-1):
self.chart.factor = self.slider.get_value()
|
定义了图标页面,具体可参照上面章节的内容
1 2 3 4 5 6 7 8 9 10 | class Screen_Main(lv.obj):
def __init__(self, app, *args, **kwds):
self.app = app
super().__init__(*args, **kwds)
self.tabview = lv.tabview(self)
self.tabview.set_style(lv.tabview.STYLE.BG, lv.style_plain_color)
self.page_buttons = Page_Buttons(self.app, self.tabview.add_tab('Button'))
self.page_slider = Page_Slider(self.app, self.tabview.add_tab('Slider'))
self.page_chart = Page_Chart(self.app, self.tabview.add_tab('Chart'))
|
这个类创建了一个标签视图,它包含三个标签页,每个标签页有不同的组件。
1 2 | screen_main = Screen_Main(lv.obj())
lv.scr_load(screen_main)
|
这行代码创建了一个主屏幕对象,并将其加载到LVGL的屏幕上。
1 2 3 4 5 6 | tim = time.ticks_ms()
while True:
if time.ticks_ms()-tim > 5:
tim = time.ticks_ms()
lv.task_handler()
lv.tick_inc(5)
|
最后,这段代码进入了一个无限循环。循环中,它每隔5毫秒调用lv.task_handler()来处理LVGL的任务,并使用lv.tick_inc(5)来通知LVGL时间已经过去了5毫秒,这样可以更新屏幕和其他LVGL相关的任务。