查看: 4400|回复: 21

还在用C编写LVGL上的画面,何不试试Python? (2)

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3300

    主题

    6547

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32028
    最后登录
    2024-4-26
    发表于 2021-5-6 10:00:09 | 显示全部楼层 |阅读模式
    还在用C编写LVGL上的画面,何不试试Python? (2)


    在上一篇中,小编为大家简单介绍了LVGL库,并且介绍了如何实现lvgl和MicroPython的绑定,使得lvgl以MicroPython模块的形式供用户通过Python进行调用,方便开发。

    本篇小编将继续承接上文,介绍如何添加输入/输出驱动,以将我们绘制的GUI界面显示到显示设备。同时,输入设备方便我们进行人机交互。

    输入/输出设备驱动添加

    既然要使用Python进行GUI开发,那么驱动当然也要注册为MicroPython模块,才像话嘛。
    同时,由于LVGL可以配置为使用不同的显示器和输入设备。这样一来,如果单纯的只提供C语言编写的驱动程序,每更换驱动就要重新将新的驱动程序替换到工程中,重新编译。考虑到注册驱动程序的本质,实际上就是调用注册函数(disp_drv_register),并将函数指针作为参数传递,函数指针指向用于访问真正的显示/输入设备。
    为了实现这一点,当在MicroPython中使用LVGL时,用C语言实现显示和输入驱动程序更有意义。但是,设备的注册是需要在MicroPython脚本中进行的,即前文所说的,驱动程序本身需要定义成对应的MicroPython模块。这样用户就可以轻松地选择和替换驱动程序,而无需构建项目和修改C文件。
    不过,从技术上讲,驱动程序不仅仅局限于C,也可以用纯纯的MicroPyhon,通过回调函数来编写。进行驱动注册的代码实现:
    1. # 所编写的模块驱动
    2. import lvgl_helper

    3. # 注册显示驱动.

    4. disp_buf1 = lv.disp_buf_t()
    5. buf1_1 = bytes(480*10)  # 声明lvgl绘制GUI的buffer,lvgl支持1-2个
    6. # buffer
    7. disp_buf1.init(buf1_1, None, len(buf1_1)//4)
    8. disp_drv = lv.disp_drv_t()
    9. disp_drv.init()
    10. disp_drv.buffer = disp_buf1
    11. disp_drv.flush_cb = lvgl_helper.flush   # 注册显示回调函数
    12. disp_drv.hor_res = 480
    13. disp_drv.ver_res = 320
    14. disp_drv.register()

    15. # 注册输入驱动

    16. indev_drv = lv.indev_drv_t()
    17. indev_drv.init()
    18. indev_drv.type = lv.INDEV_TYPE.POINTER
    19. indev_drv.read_cb = lvgl_helper.capture # 注册输入回调函数
    20. indev_drv.register()
    复制代码
    这里,我们定义了一个叫做lvgl_helper的模块,其中包括一个叫做flush的函数,负责将lvgl绘制好的GUI刷新到显示设备,另一个函数叫做capture,负责处理输入请求,获取用户输入。

    接下来,让我们看看这两个函数是怎么实现的。

    首先是lvgl_helper.flush函数,具有三个参数,作用就是将lvgl绘制的目标区域刷新到显示设备:
    1. STATIC mp_obj_t mp_flush(mp_obj_t disp_drv, mp_obj_t area, mp_obj_t color){
    2.         // 显示设备指针
    3.         lv_disp_drv_t *disp_ptr = GET_PTR_FROM_OBJ(lv_disp_drv_t, disp_drv);
    4.         // 待刷新区域
    5.         lv_area_t *area_ptr = GET_PTR_FROM_OBJ(lv_area_t, area);
    6.         // 待刷新目标地址指针
    7.         lv_color_t *color_ptr = GET_PTR_FROM_OBJ(lv_color_t, color);
    8.         // 获取刷新区域宽和高
    9.         uint16_t w = lv_area_get_width(area_ptr);
    10.         uint16_t h = lv_area_get_height(area_ptr);
    11.         // 真正的刷新函数,根据不同硬件定制化实现
    12.         Update_FrameBuffer((void*)color_ptr, w, h, COLOR_DEPTH, NULL);
    13.         // 很重要,在刷新完成后,需要通知lvgl,刷新完毕,可以继续绘制,否则会一直阻塞
    14.         // 直到刷新完毕
    15.         lv_disp_flush_ready(disp_ptr);
    16.         return mp_const_none;
    17. }
    18. MP_DEFINE_CONST_FUN_OBJ_3(mp_flush_obj, mp_flush);
    复制代码
    与之对应的输入函数,看似简单一点,只有2个参数,其目的就是获取屏幕触摸坐标:
    1. STATIC mp_obj_t mp_capture(mp_obj_t indev_drv, mp_obj_t data){    // 输入设备指针
    2.    lv_indev_drv_t *indev_ptr = GET_PTR_FROM_OBJ(lv_indev_drv_t, indev_drv);
    3.    // 存储获取的触摸位置坐标(x,y)
    4.    lv_indev_data_t* data_ptr = GET_PTR_FROM_OBJ(lv_indev_data_t, data);
    5.    // 触摸屏驱动,需要自行实现
    6.    DEMO_ReadTouch(indev_ptr, data_ptr, resolution.w, resolution.h);        
    7.    return mp_const_none;
    8. }
    9. MP_DEFINE_CONST_FUN_OBJ_2(mp_capture_obj, mp_capture);
    复制代码
    有了显示和输入设备的驱动,就可以算的上万事具备了,不过,东风还没来。


    lvgl规定,画面的刷新以及响应输入设备,是通过周期性的调用lv.task_handler()函数实现的,同时需要通过lv.tick_inc(x)函数提供内部时钟。而对于MicroPython,函数的周期性调用有点特殊,是通过周期性的调用mp_sched_schedule函数来实现的。

    为了做到周期性调用这一硬性规定,推荐的做法是实现一个timer,软件/硬件的都可以,但是硬件时钟当然最好,并将周期函数以callback的形式注册到timer中:
    1. def timer_callback(self):
    2.     lv.tick_inc(10)
    3.     lv.task_handler()
    4. timer.init(50) # 刷新时间可以自行调整
    5. timer.callback(timer_callback)
    复制代码
    这样,一切就都准备就绪了,让我们来搭建一个简单的界面玩一下。

    实战操练与效果展示
    这次的小demo包括:按钮,滑动条,键盘,文本框以及一个图片控件。
    先看下实际效果:
    1.png
    2.png
    3.png
    是不是界面很熟悉,是的,小编前面说过了,MicroPython环境依托于openART软件包,因此,我们可以使用openMV IDE进行代码的编写和下载,并通过预览窗口进行GUI预览。

    下面逐段说明一下控件所对应的代码实现:

    0) 初始化:
    1. import lv
    2. lv.init()
    3. scr = lv.obj() # declare the screen to show
    复制代码
    1) 按钮
    1. btn = lv.btn(lv.scr_act())
    2. # 对齐属性以及位置坐标
    3. btn.align(lv.scr_act(), lv.ALIGN.IN_BOTTOM_LEFT, 10, -20)
    4. btn.toggle() # 翻转显示,蓝底白字/白底蓝字
    5. label = lv.label(btn) # 控件名字
    6. label.set_text("start")
    复制代码
    2) 滑动条:
    1. slider = lv.slider(lv.scr_act())
    2. slider.align(lv.scr_act(), lv.ALIGN.OUT_RIGHT_TOP, -50, -10)
    3. # 滑动条宽和高
    4. slider.set_width(10)
    5. slider.set_height(300)
    6. # 滑动条范围
    7. slider.set_range(10, 200)
    8. # 滑动条初始值
    9. slider.set_value(100, 0)
    复制代码
    3) 键盘:
    1. keyboard = lv.keyboard(lv.scr_act())
    2. # 数字键盘
    3. # keyboard.set_mode(keyboard.MODE.NUM)
    4. # 大写字母键盘
    5. # keyboard.set_mode(keyboard.MODE.TEXT_UPPER)
    6. # 小写字母键盘
    7. # keyboard.set_mode(keyboard.MODE.TEXT_LOWER)
    8. # 特殊符号键盘
    9. # keyboard.set_mode(keyboard.MODE.SPECIAL)
    10. keyboard.align(lv.scr_act(), lv.ALIGN.IN_TOP_LEFT, 0, 0)
    复制代码
    4) 文本框:
    1. text = lv.textarea(lv.scr_act())
    2. text.align(lv.scr_act(), lv.ALIGN.IN_BOTTOM_LEFT, 0, 0)
    3. # 设置控件为可拖拽属性
    4. text.drag(True)
    复制代码
    5) 图片:
    1. # 读取图片数据
    2. img_data = open("/sd/blue_flower_16.txt").read()
    3. img = lv.img(lv.scr_act())
    4. img.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
    5. # 设置图像属性
    6. img_dsc = lv.img_dsc_t(
    7.     {
    8.         "header": {"always_zero": 0, "w": 100, "h": 75, "cf": lv.img.CF.TRUE_COLOR},
    9.         "data_size": len(img_data),
    10.         "data": img_data,
    11.     }
    12. )
    13. img.set_src(img_dsc)
    复制代码
    ------------------------------------------------------------------------------------------------------
    尽管是几个简单的控件的使用,验证了我们的带MicroPython绑定的lvgl已经成功移植到了我们的板子上。


    相信大家看完之后,已经跃跃欲试了,那就开始动手吧!

    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    3 小时前
  • 签到天数: 558 天

    [LV.9]以坛为家II

    34

    主题

    5916

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    5702
    最后登录
    2024-4-26
    发表于 2021-6-16 16:17:42 | 显示全部楼层
    上手转换使用工具的难度大不大?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    1 小时前
  • 签到天数: 1783 天

    [LV.Master]伴坛终老

    65

    主题

    7542

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    12758
    最后登录
    2024-4-26
    发表于 2021-6-16 16:18:32 | 显示全部楼层
    LVGL不错
    回复

    使用道具 举报

  • TA的每日心情
    开心
    半小时前
  • 签到天数: 1279 天

    [LV.10]以坛为家III

    21

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    13243
    最后登录
    2024-4-26
    发表于 2021-6-16 16:20:02 | 显示全部楼层
    我可以试试python, 硬件你提供不?
    跟着日天混 ,三天饱九顿!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-21 11:31
  • 签到天数: 35 天

    [LV.5]常住居民I

    7

    主题

    1876

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1802
    最后登录
    2024-4-1
    发表于 2021-6-16 16:24:41 | 显示全部楼层
    要用python写,前提的工作量不少。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    昨天 17:02
  • 签到天数: 618 天

    [LV.9]以坛为家II

    0

    主题

    1809

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    4507
    最后登录
    2024-4-25
    发表于 2021-6-16 18:39:50 | 显示全部楼层
    这可以,python强大
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2023-8-30 17:43
  • 签到天数: 306 天

    [LV.8]以坛为家I

    14

    主题

    1746

    帖子

    4

    金牌会员

    Rank: 6Rank: 6

    积分
    2531
    最后登录
    2023-8-30
    发表于 2021-6-16 19:47:15 | 显示全部楼层
    相当不错,内容分及其丰富
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-6-16 07:43
  • 签到天数: 155 天

    [LV.7]常住居民III

    9

    主题

    519

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1150
    最后登录
    2021-11-12
    发表于 2021-6-17 07:26:45 | 显示全部楼层
    用python的确简单多了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2 小时前
  • 签到天数: 2628 天

    [LV.Master]伴坛终老

    45

    主题

    5184

    帖子

    22

    金牌会员

    Rank: 6Rank: 6

    积分
    10677
    最后登录
    2024-4-26
    发表于 2021-6-17 08:56:04 | 显示全部楼层
    现在做开发真是方便,直接调库完事。
    签到签到
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2023-1-31 09:34
  • 签到天数: 202 天

    [LV.7]常住居民III

    7

    主题

    1515

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3816
    最后登录
    2024-2-19
    发表于 2021-6-17 09:18:57 | 显示全部楼层
    做软件的同事经常和我说三天上手python 一周做项目
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-26 11:16 , Processed in 0.139549 second(s), 29 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表