UI设计工具文档UI设计工具文档
反馈钉钉群
  • AC791
  • AC792
  • AC63
  • GPMCU
  • AD14/15/17/18/AD104
  • AD16
  • AD24
  • AC82
  • AW30
  • AW31
反馈钉钉群
  • AC791
  • AC792
  • AC63
  • GPMCU
  • AD14/15/17/18/AD104
  • AD16
  • AD24
  • AC82
  • AW30
  • AW31
  • 1.工具前言

    • 1.1.工具首页
    • 1.2.前言说明
  • 2.快速使用

    • 2.1.快速使用
    • 2.2.快速上手
    • 2.3.板子配置
    • 2.4.视频教程
    • 2.5.硬件资料
  • 3.控件说明

    • 3.1.控件说明
    • 3.2.基础控件

      • 页面
      • 按钮
      • 图片按钮
      • 标签
      • 图片
      • 文本框
      • 开关
      • 数字微调器
      • 复选框
      • 下拉框
      • 进度条
      • Lottie动画
      • 帧动画
      • 图表
      • 滑动条
      • 弧线
      • 仪表盘
      • 相册
    • 3.3.菜单控件

      • 圆弧菜单
      • 齿轮菜单
      • 列表菜单
      • 曲线菜单
      • 网格菜单
      • 万花筒菜单
      • 多边形菜单
      • 轮盘菜单
    • 3.4.容器控件

      • 通用容器
      • Flex布局
  • 4.高级功能

    • 4.1.时间轴动画
    • 4.2.模型绑定
    • 4.3.资源管理
    • 4.4.国际化
    • 4.5.硬件仿真
    • 4.6.自动化测试
    • 4.7.控件组
    • 4.8.菜单管理
    • 4.9.页面管理
    • 4.10.主题
    • 4.11.动态页面
    • 4.12.AI助手(MCP)
  • 5.插件系统

    • 5.1.插件说明
    • 5.2.开发指南
    • 5.3.字体合并
    • 5.4.图片编辑
    • 5.5.截图
    • 5.6.项目合并
    • 5.7.项目属性编辑
    • 5.8.视频转图片
    • 5.9.图片转换
  • 6.使用案例

    • 6.1.倒计时案例
    • 6.2.键盘和鼠标滚轮控制菜单滑动
    • 6.3.自定义Symbol
    • 6.4.暗色键盘主题
    • 6.5.设置多个资源分区
  • 7.常见问题

    • 7.1.问题说明
    • 7.2.编译问题
    • 7.3.LVGL问题
    • 7.4.仿真问题
    • 7.5.UI工具问题
    • 7.6.其他问题
  • 8.工具杂项

    • 8.1.杂项1
    • 8.2.杂项2
    • 8.3.工具生成API接口

仿真问题

本章目录
  • 1. 图片控件设置了图片,但是编译仿真后没有显示图片
  • 2. 如何区分是键盘还是鼠标触发的 Click 事件
  • 3. 仿真程序启用性能/内存监控
  • 4. 打包资源时,出现 Unable to load image file 错误
  • 5. 仿真出现闪退现象,例如新添菜单后点击菜单时仿真闪退
  • 6. 控件使用 bmp 图片资源,图片不显示
  • 7. 控件使用 16 位深的 bmp 图片资源,图片显示异常
  • 8. 顶层页面 Gesture 事件无法触发
  • 9. 使用字库中新添加的字体时,仿真出现字体不一致、乱码
  • 10. 标签控件的文本出现往下偏移的问题
  • 11. 控件设置阿拉伯文本,仿真和工具画布对不上
本章正文

图片控件设置了图片,但是编译仿真后没有显示图片

  • 原因:没有设置图片路径,或者图片文件不存在。
  • 解决方案:通过检查生成代码,检查图片路径是否正确,图片文件是否存在,是否需要先打包工程,再编译仿真。

下面这种情况,工程设置了图片路径,但是因为将静态图片的压缩方式设置为 Bin ,在编译前,没有先进行打包,导致图片文件没有正常生成,所以图片文件不存在无法正常显示。

提示

当设置静态图片的压缩方式设置为 Bin 时,如果对控件图片进行了修改,或者在 编译资源管理 中进行了图片资源的增删,需要先进行打包,再编译仿真。

如何区分是键盘还是鼠标触发的 Click 事件

  • 解决方法:通过判断事件参数,来区分是键盘还是鼠标触发的 Click 事件。
lv_indev_t * act_indev = lv_indev_get_act();
lv_indev_t * event_indev = (lv_indev_t *)lv_event_get_param(e);
if (act_indev && act_indev == event_indev) {
	lv_indev_type_t type = lv_indev_get_type(act_indev);
	if (type == LV_INDEV_TYPE_ENCODER) {
		LV_LOG_WARN("encoder click");
	} else if (type == LV_INDEV_TYPE_KEYPAD) {
		LV_LOG_WARN("keypad click");
	} else if (type == LV_INDEV_TYPE_BUTTON) {
		LV_LOG_WARN("button click");
	} else if (type == LV_INDEV_TYPE_POINTER) {
		LV_LOG_WARN("pointer click");
	}
}

仿真程序启用性能/内存监控

  • 解决方法:在 项目 -> 项目属性 -> 仿真配置 中启用 实时性能监控、实时内存监控。

提示

  • 启用 实时性能监控、实时内存监控 本质上,是启用 LV_USE_PERF_MONITOR 和 LV_USE_MEM_MONITOR。如果在设备内核上需要启用,可以在SDK中启用这两个宏定义。
  • 在某些仿真内核里,可能启用了 LV_USE_PERF_MONITOR,但是仿真程序还是没有内存监控的label,这可能内核启用了 LV_MEM_CUSTOM 所导致的,说明这时候内核是使用自定义的内存管理,lvgl无法监控内存使用情况。
// lvgl\src\core\lv_refr.c
#if LV_USE_MEM_MONITOR && LV_MEM_CUSTOM == 0 && LV_USE_LABEL
    lv_obj_t * mem_label = mem_monitor.mem_label;
    if(mem_label == NULL) {
        mem_label = lv_label_create(lv_layer_sys());
        lv_obj_set_style_bg_opa(mem_label, LV_OPA_50, 0);
        lv_obj_set_style_bg_color(mem_label, lv_color_black(), 0);
        lv_obj_set_style_text_color(mem_label, lv_color_white(), 0);
        lv_obj_set_style_pad_top(mem_label, 3, 0);
        lv_obj_set_style_pad_bottom(mem_label, 3, 0);
        lv_obj_set_style_pad_left(mem_label, 3, 0);
        lv_obj_set_style_pad_right(mem_label, 3, 0);
        lv_label_set_text(mem_label, "?");
        lv_obj_align(mem_label, LV_USE_MEM_MONITOR_POS, 0, 0);
        mem_monitor.mem_label = mem_label;
    }

    if(lv_tick_elaps(mem_monitor.mem_last_time) > 300) {
        mem_monitor.mem_last_time = lv_tick_get();
        lv_mem_monitor_t mon;
        lv_mem_monitor(&mon);
        uint32_t used_size = mon.total_size - mon.free_size;;
        uint32_t used_kb = used_size / 1024;
        uint32_t used_kb_tenth = (used_size - (used_kb * 1024)) / 102;
        lv_label_set_text_fmt(mem_label,
                              "%"LV_PRIu32 ".%"LV_PRIu32 " kB used (%d %%)\n"
                              "%d%% frag.",
                              used_kb, used_kb_tenth, mon.used_pct,
                              mon.frag_pct);
    }
#endif

打包资源时,出现 Unable to load image file 错误

  • 原因:图片资源数据异常,转换工具无法正常加载图片资源文件。
  • 解决方法:尝试将图片资源文件转换为其他格式,如 png、jpg 等。如果是bmp,可以在 https://online-converting.com/image/convert2bmp/# 网站上,将图片资源文件重新转换为 bmp 格式尝试下。

仿真出现闪退现象,例如新添菜单后点击菜单时仿真闪退

  • 解决方法:先打包同步资源,再仿真

控件使用 bmp 图片资源,图片不显示

  • 原因:在使用 bmp 图片资源时,如果当前的 色彩深度 为 16 位,那么 bmp 图片资源的 色彩深度 必须为 16 位。同理,如果当前的 色彩深度 为 32 位,那么 bmp 图片资源的 色彩深度 必须为 32 / 24 位。
  • 解决方法:将 bmp 图片资源的 色彩深度 设置为与当前 色彩深度 一致。
  • 注意:如果不是使用 原图 的方式,在打包时会自动压缩图片资源,所以在设备上可以忽略这个问题,但只是会在仿真时显示不出来。

控件使用 16 位深的 bmp 图片资源,图片显示异常

  • 原因:在使用 16 位深的 bmp 图片资源时,如果图片不是 RGB565 格式,那么在显示时会出现异常。
  • 解决方法:将 bmp 图片资源的 色彩格式 设置为 RGB565 格式。

顶层页面 Gesture 事件无法触发

  • 原因:顶层页面是在 lv_layer_top() 作为父控件创建的,而页面的 LV_OBJ_FLAG_GESTURE_BUBBLE 标识默认为true,所以 Gesture 事件会发送给 lv_layer_top()。
  • 解决方法:在创建顶层页面时,页面启用 清理标识 ,将 LV_OBJ_FLAG_GESTURE_BUBBLE 标识清除掉,这样 Gesture 事件就会发送给顶层页面了。

使用字库中新添加的字体时,仿真出现字体不一致、乱码

  • 原因:新添加的字体的字体大小与控件文本设置的字体大小不一致
  • 解决方法:更改字体大小

标签控件的文本出现往下偏移的问题

  • 原因:字体文件的行高(line height)是根据字体中所有字形的最大高度来计算的。当字体资源中包含特殊字符(如 〲〬,Unicode编码 U+3032)时,这些字符的高度远超普通文本字符,导致整个字体文件的行高被拉高。最终造成普通字符在显示时相对于其容器出现向下偏移。
  • 解决方法:避免在字体资源中引用这些高度异常的特殊字符,确保生成的字体文件使用普通字符的行高标准。

控件设置阿拉伯文本,仿真和工具画布对不上

  • 原因:阿拉伯字母和中文、英文不一样,同一个字母会根据它在词里的位置(词首、词中、词尾、独立)连笔成不同的形状,这些随位置变化的字形在 Unicode 里叫“呈现形式”(Presentation Forms)。LVGL 要正常显示阿拉伯文本,需要同时满足下面几个条件,否则仿真效果就会和工具画布对不上:
    • 仿真内核要开启阿拉伯文支持:lvgl-simulator\lv_conf.h 里需要开启两个宏:
      • LV_USE_BIDI:负责从右到左的排版(文字顺序反转);
      • LV_USE_ARABIC_PERSIAN_CHARS:负责连笔处理(把输入字母替换成呈现形式码点)。
    • 字体里要有连笔后的字符:开启处理后,LVGL 会把输入的阿拉伯字母转成对应的呈现形式码点,再去字体里找字形(标准阿拉伯字母转到 U+FE70–U+FEFF,波斯/乌尔都字母转到 U+FB50–U+FDFF)。如果工具生成字体文件时没有包含这些码点,LVGL 就找不到字形,连笔后的字就显示不出来了。
  • 解决方法:
    • 确认并开启 lvgl-simulator\lv_conf.h 里的 LV_USE_BIDI、LV_USE_ARABIC_PERSIAN_CHARS 两个宏定义;
    • 在 编译资源管理 里添加需要的字体、字号,并加上对应的字符范围:
      • 标准阿拉伯语:基础字母 U+0600–U+06FF + 连笔变体 U+FE70–U+FEFF;
      • 如果文本包含波斯/乌尔都字母(如 پ چ ژ ک گ ی),还要加 U+FB50–U+FDFF;
    • 重新打包、编译仿真。

提示

附:这些字符范围是从哪来的

开启连笔处理后,LVGL 会把输入字符映射到下面的 Unicode 区间,所以字体要同时包含“输入的基础码点”和“映射后的呈现形式码点”:

输入(基础块)输出映射到块名
标准阿拉伯字母 U+0622–U+064A(ب ت ث ج … ل م ن و ه ي 等)U+FE70–U+FEFC阿拉伯文 Presentation Forms-B
波斯/乌尔都字母 پ U+067E、چ U+0686、ژ U+0698、ک U+06A9、گ U+06AF、ی U+06CCU+FB50–U+FDFF(自 FB56/FB7A/FB8A/FB8E/FB92/FBFC 起)阿拉伯文 Presentation Forms-A
拉姆-阿列夫连字 ل + آ/أ/إ/اU+FEF5–U+FEFB同上(Forms-B)
波斯数字 U+06F0–U+06F9、tatweel U+0640保持不变(不映射)—

连笔处理发生在设置文本时(不是渲染时),存入控件的已经是映射后的呈现形式码点,lv_label_get_text() 读回的也是整形后的字符串,不要拿原始文本去比较/搜索。

提示

LVGL 的阿拉伯整形是简化实现(非 HarfBuzz/完整双向算法),个别边界情况与画布仍可能有细微差异,例如独立 hamza U+0621 不做替换、阿拉伯-印度数字 U+0660–U+0669 只参与排版不参与连笔等。

上一页
7.3.LVGL问题
下一页
7.5.UI工具问题