解码LVGL中文字体、输入框、键盘

news/2025/11/10 10:59:48/文章来源:https://www.cnblogs.com/YouEmbedded/p/19205470

字体控件(lv_label + 字体管理):中文显示方案

LVGL 内置字体仅支持英文 / 数字,中文需 “提取固定汉字” 或 “动态加载 TTF”。

场景 1:有限汉字(固定文本,如 “登录”“取消”)

适用于固定中文文本,通过 LVGL 字库生成器提取汉字转 C 数组。

  • Step1:生成中文字库(关键参数)

    打开工具:LVGL 在线字库生成器;

    配置参数:

    参数名 配置值 / 说明 作用
    Name simkai_26(符合 C 标识符规则) 字库名称
    Size 26(像素,按屏幕分辨率调整) 字体大小
    Bpp 4bit(平衡质量与内存) 像素色深
    TTF/WOFF font 上传中文字体(如 simfang.ttf) 字体源文件
    Range/Characters 输入所需汉字(如 “登录 注册 123”) 仅提取需要的字符(减少内存)

    生成 simkai_26.c (数组类型为 lv_font_t)。

  • Step2:代码使用(绑定到按钮 / 标签)

    CMakeLists.txt下将字体的.c文件加入生成可执行文件的依赖

    image

    #include "lvgl/lvgl.h"
    LV_FONT_DECLARE(simkai_26); // 声明中文字库
    extern const lv_font_t simkai_26;  //声明外部变量/*** 创建带中文字体的按钮* @param parent:父对象* @param text:按钮文本(如“登录”)* @param x/y_ofs:偏移量*/
    lv_obj_t *btn_create_with_cn(lv_obj_t *parent, const char *text, int32_t x_ofs, int32_t y_ofs) {// 创建按钮lv_obj_t *btn = lv_btn_create(parent);lv_obj_set_size(btn, 100, 70);lv_obj_align(btn, LV_ALIGN_CENTER, x_ofs, y_ofs);// 创建标签(显示中文)lv_obj_t *label = lv_label_create(btn);lv_label_set_text(label, text);// 绑定中文字体(核心:否则乱码)lv_obj_set_style_text_font(label, &simkai_26, LV_PART_MAIN);lv_obj_center(label);return btn;
    }// 调用示例(登录/注册按钮)
    void btn_cn_demo(void) {lv_obj_t *scr = lv_scr_act();btn_create_with_cn(scr, "登录", -100, 0);  // 左偏100pxbtn_create_with_cn(scr, "注册", 100, 0);   // 右偏100px
    }
    

效果:

image

场景 2:不限汉字(动态文本,如用户输入)

适用于动态中文场景(如新闻展示、用户输入框、可变文本内容),核心是通过 LVGL 集成 FreeType 库 实时加载 TTF/OTF 字体文件,支持任意汉字及字体样式(粗体、斜体)。

核心前提

FreeType 是 LVGL 的扩展库,用于运行时生成字体位图,无需预编译字体(,灵活适配动态文本需求。

官方文档:https://www.freetype.org

Step1:启用 FreeType 并配置(修改 lv_conf.h)

必须先在 LVGL 配置文件中启用 FreeType,核心配置项需与官方文档一致:

/*FreeType 字体库配置*/
#define LV_USE_FREETYPE 1  // 启用 FreeType
#if LV_USE_FREETYPE#define LV_FREETYPE_USE_LVGL_PORT 0  // Linux 用原生接口,无需 LVGL 适配#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 65535  // 大内存,缓存拉满
#endif/*FreeType 字体库配置*/
#define LV_USE_FREETYPE 1  // 启用 FreeType
#if LV_USE_FREETYPE#define LV_FREETYPE_USE_LVGL_PORT 1  // 复用 LVGL 适配的开发板文件系统/内存#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 4096  // 适配 128KB RAM,缓存 4096 个常用字形
#endif

CMakeList.txt中添加freetype库的内容

# 添加字体库头文件
# 核心修正:给 LVGL 目标单独添加包含路径(LVGL 编译时会用到)
target_include_directories(lvglPRIVATE${PROJECT_SOURCE_DIR}/my_app/libs/freetype/include/freetype2
)# 同时确保你的项目目标也能识别(若需自己的代码调用 FreeType)
target_include_directories(${PROJECT_NAME}PRIVATE${PROJECT_SOURCE_DIR}/my_app/libs/freetype/include/freetype2
)
# 指定外部库的搜索路径
link_directories(${PROJECT_SOURCE_DIR}/my_app/libs/freetype/lib)
# 在 find_package(Freetype) 之前添加,替换成你的 FreeType 安装路径
set(CMAKE_PREFIX_PATH "/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/my_app/libs/freetype" ${CMAKE_PREFIX_PATH})
# 查找已安装的 FreeType 库(核心步骤)
find_package(Freetype REQUIRED)
#链接freetype 将Freetype::Freetype加在后面
target_link_libraries(main lvgl lvgl::examples lvgl::demos lvgl::thorvg ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${Libdrm_LIBRARIES} m pthread Freetype::Freetype)

Step2:集成 FreeType 到项目(分场景适配)

根据运行环境选择集成方式,嵌入式设备优先「源码集成」(节省 FLASH),UNIX / 开发板可选择「编译安装」。

场景 A:嵌入式设备——无操作系统(推荐源码集成)

直接将 FreeType 源码嵌入项目,使用 LVGL 提供的精简配置(仅保留核心功能):

  • 下载 FreeType 源码:从 FreeType 官网 下载最新稳定版(如 2.13.2)。
  • 复制源码到项目:将 FreeType 源码目录复制到项目中(如 project/libs/freetype/)。
  • 修改项目编译脚本(Makefile/CMake):添加编译参数和源码文件,需包含 LVGL 提供的配置头文件:
# FreeType 编译宏(必须,指定 LVGL 精简配置)
CFLAGS += -DFT2_BUILD_LIBRARY  # 编译 FreeType 库本身
CFLAGS += -DFT_CONFIG_MODULES_H=<lvgl/src/libs/freetype/ftmodule.h>  # LVGL 精简模块配置
CFLAGS += -DFT_CONFIG_OPTIONS_H=<lvgl/src/libs/freetype/ftoption.h>  # LVGL 精简选项配置# 头文件路径(FreeType 源码的 include 目录)
CFLAGS += -I./libs/freetype/include# 需编译的 FreeType 核心源码(LVGL 推荐最小集,节省 FLASH)
FT_CSRCS += ./libs/freetype/src/base/ftbase.c
FT_CSRCS += ./libs/freetype/src/base/ftbitmap.c
FT_CSRCS += ./libs/freetype/src/base/ftdebug.c
FT_CSRCS += ./libs/freetype/src/base/ftglyph.c
FT_CSRCS += ./libs/freetype/src/base/ftinit.c
FT_CSRCS += ./libs/freetype/src/cache/ftcache.c
FT_CSRCS += ./libs/freetype/src/gzip/ftgzip.c
FT_CSRCS += ./libs/freetype/src/sfnt/sfnt.c
FT_CSRCS += ./libs/freetype/src/smooth/smooth.c
FT_CSRCS += ./libs/freetype/src/truetype/truetype.c# 将 FreeType 源码加入项目编译
CSRCS += $(FT_CSRCS)
  • 复制 TTF 字体文件:将需要的中文字体(如 simkai.ttfsimfang.ttf)放到设备可访问路径(如 ./fonts/,嵌入式需放在文件系统挂载目录)。

场景 B:UNIX / 开发板——有操作系统(编译安装库)

适合有操作系统(如 Linux、Android)的设备,通过编译生成动态库链接使用:

  • 下载 FreeType 源码:同上。
  • 编译安装 FreeType
# 进入源码目录
cd freetype-2.13.2#注意!!!修改./configure和makefile的权限,安装在系统路径要加sudo# 配置编译(嵌入式开发板需替换交叉编译器,如 arm-linux-gcc)
# 本地 UNIX 直接用:./configure --prefix=安装路径
# 开发板交叉编译示例:
export CC=arm-linux-gcc  # 设置交叉编译器
./configure --host=arm-linux --prefix=/usr/local/freetype-arm \--enable-shared=yes --enable-static=no# 编译并安装(生成动态库 libfreetype.so)
make 
make install
  • 部署库文件和字体
    • 复制编译生成的 libfreetype.so.* 到开发板 /lib 或 /usr/lib 目录;
    • 复制 TTF 字体文件到开发板可访问路径(如 /usr/share/fonts/ 或 ./fonts/)。
  • 项目链接 FreeType:编译项目时添加链接参数:
gcc your_code.c -o app \-I/usr/include/freetype2 -I./lvgl/src \-L/usr/local/lib -lfreetype  # 链接 FreeType 库

Step3:代码实现(动态加载 TTF 字体并显示)

遵循 LVGL 官方 API 规范

#include "lvgl/lvgl.h"
#include "lvgl/src/libs/freetype/lv_freetype.h"  // FreeType 核心头文件
/*** 动态加载 TTF 字体并创建中文标签* @param parent:父对象(如屏幕、容器)* @param ttf_path:TTF 字体文件路径(绝对/相对路径)* @param font_size:字体大小(像素)* @param text:要显示的中文文本(支持任意汉字)* @param style:字体样式(LV_FREETYPE_FONT_STYLE_* 组合)* @return 成功返回标签对象,失败返回 NULL*/
lv_obj_t *freetype_create_label(lv_obj_t *parent, const char *ttf_path,lv_freetype_font_render_mode_t render_mode, uint32_t font_size, const char *text, uint32_t style) {if (!ttf_path || !text) return NULL;// 创建 FreeType 字体配置(LVGL 8+ 标准接口)lv_font_t *font = lv_freetype_font_create(ttf_path, render_mode ,font_size, style);if (!font) {LV_LOG_ERROR("TTF 字体加载失败:路径=%s", ttf_path);return NULL;}// 创建标签并设置文本lv_obj_t *label = lv_label_create(parent);lv_label_set_text(label, text);  // 支持任意中文(只要 TTF 字体包含该字符)// 设置标签样式(LVGL 8+ 新接口:lv_obj_set_style_*)lv_obj_set_style_text_font(label, font, 0);          // 绑定 FreeType 字体lv_obj_set_style_text_color(label, lv_color_hex(0x000000), 0);  // 文本颜色(黑色)lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);    // 文本居中lv_obj_set_style_text_line_space(label, font_size / 2, 0);       // 行间距(可选)// 对齐标签(屏幕中心)lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);// 注意:字体对象 font 需在不需要时释放(避免内存泄漏)// lv_freetype_font_delete(font);  // 若标签长期使用,请勿立即释放return label;
}
/*** 示例:多样式文本展示(正常、粗体、斜体、粗斜体)*/
void freetype_demo(void) {lv_obj_t *scr = lv_scr_act();  // 获取当前屏幕// 样式宏说明(官方定义,支持组合)// 加载不同样式的中文标签(假设 TTF 字体路径为 /home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf)freetype_create_label(scr, "/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf",LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, "正常样式:动态中文", LV_FREETYPE_FONT_STYLE_NORMAL);freetype_create_label(scr, "/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf",LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, "粗体样式:动态中文", LV_FREETYPE_FONT_STYLE_BOLD);freetype_create_label(scr, "/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf",LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, "斜体样式:动态中文", LV_FREETYPE_FONT_STYLE_ITALIC);freetype_create_label(scr, "/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP,24, "粗斜体样式:动态中文", LV_FREETYPE_FONT_STYLE_ITALIC|LV_FREETYPE_FONT_STYLE_ITALIC);// 调整各标签位置(避免重叠)lv_obj_set_y(lv_obj_get_child(scr, 0), -60);  // 第一个标签上移 60pxlv_obj_set_y(lv_obj_get_child(scr, 1), -20);  // 第二个标签上移 20pxlv_obj_set_y(lv_obj_get_child(scr, 2), 20);   // 第三个标签下移 20pxlv_obj_set_y(lv_obj_get_child(scr, 3), 60);   // 第四个标签下移 60px
}/*** 输入框 + 键盘 联动示例(实现中文输入)*/
void freetype_textarea_demo(void) {lv_obj_t *scr = lv_scr_act();// 加载输入框用的字体(22px 正常样式)lv_font_t *input_font = lv_freetype_font_create("/home/wby/LVGL/Ubuntu/lv_port_linux-9.2/resource/font/simkai.ttf",LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 22, LV_FREETYPE_FONT_STYLE_NORMAL);if (!input_font) return;// 创建输入框(lv_textarea)lv_obj_t *textarea = lv_textarea_create(scr);lv_obj_set_size(textarea, 300, 80);lv_obj_align(textarea, LV_ALIGN_CENTER, 0, -30);lv_obj_set_style_text_font(textarea, input_font, 0);  // 输入框文本绑定 FreeType 字体lv_textarea_set_placeholder_text(textarea, "请输入中文...");  // 占位提示// 创建键盘(lv_keyboard),绑定输入框lv_obj_t *keyboard = lv_keyboard_create(scr);lv_obj_set_size(keyboard, LV_HOR_RES, LV_VER_RES / 2);lv_keyboard_set_textarea(keyboard, textarea);  // 键盘输入内容同步到输入框// 键盘按钮文本也使用 FreeType 字体(可选,统一风格)//lv_obj_set_style_text_font(keyboard, input_font, 0);
}// 主函数调用(LVGL 初始化后执行)
void lv_app_init(void) {lv_init();  // 初始化 LVGL(已有则无需重复)// ... 初始化显示驱动、输入驱动 ...freetype_demo();               // 字体样式展示// freetype_textarea_demo();    // 中文输入功能(按需启用)
}

效果:

image

Step4:关键注意事项

  • 资源释放:通过 lv_freetype_font_create() 创建的字体对象,在不需要时需调用 lv_freetype_font_delete(font) 释放,避免内存泄漏。
  • 文件路径兼容性
    • 未启用 LV_FREETYPE_USE_LVGL_PORT 时,路径为操作系统原生路径(如 /usr/share/fonts/);
    • 启用后,路径遵循 LVGL 文件系统接口(如 SDFS:/fonts/),需先初始化 LVGL 文件系统。
  • 缓存配置合理性LV_FREETYPE_CACHE_SIZE 不宜过小(否则频繁重建缓存,性能下降),也不宜过大(占用过多 RAM),嵌入式设备建议 16KB~64KB。
  • 字体文件完整性:确保 TTF 字体包含所需汉字(如宋体、楷体支持完整中文,部分精简字体可能缺失生僻字)。

常用函数接口解析:

/*** 初始化 LVGL FreeType 模块(使用所有 FreeType 字体接口前必须调用)* @param max_glyph_cnt 最大缓存字形数量(缓存常用字形以提升渲染速度,建议设 1024~4096,根据内存调整)* @return 操作结果(LV_RESULT_OK=初始化成功;LV_RESULT_INVALID_PARAM=参数非法;LV_RESULT_ERROR=FreeType 库未集成或初始化失败)* @note 整个 LVGL 生命周期中仅需调用一次;*       缓存数量越大,频繁渲染相同字符时速度越快,但占用内存越多;*/
lv_result_t lv_freetype_init(uint32_t max_glyph_cnt);/*** 基于 FreeType 库创建 TTF/OTF 字体对象(支持中文、英文等任意字体包含的字符)* @param pathname TTF/OTF 字体文件路径(绝对路径或相对 LVGL 运行目录的路径,不可为 NULL,需确保文件存在且有权限访问)* @param render_mode 字体渲染模式(枚举类型:LV_FREETYPE_FONT_RENDER_MODE_BITMAP=位图渲染(默认推荐);LV_FREETYPE_FONT_RENDER_MODE_DIRECT=直接渲染)* @param size 字体显示大小(单位:像素,需大于 0,如 24=24px 字体)* @param style 字体样式(枚举类型:LV_FREETYPE_FONT_STYLE_NORMAL=正常;LV_FREETYPE_FONT_STYLE_BOLD=粗体;LV_FREETYPE_FONT_STYLE_ITALIC=斜体;支持组合使用,如 BOLD|ITALIC=粗斜体)* @return 成功返回 LVGL 字体对象(lv_font_t*),失败返回 NULL(路径错误、字体文件损坏、参数非法、FreeType 未初始化均会导致失败)* @note  字体对象使用后需调用 lv_freetype_font_delete 释放,避免内存泄漏;*        若字体绑定的控件(如标签)长期使用,需在控件销毁后再释放字体;*        支持 UTF-8 编码文本,只要字体文件包含对应字符即可正常渲染*/
lv_font_t *lv_freetype_font_create(const char *pathname, lv_freetype_font_render_mode_t render_mode, uint32_t size, lv_freetype_font_style_t style);/*** 释放 FreeType 创建的字体对象(回收字体占用的内存和资源)* @param font 待释放的 FreeType 字体对象(可为 NULL,NULL 时无操作)* @return 无返回值* @note 释放后不可再使用该字体对象(需重新调用 lv_freetype_font_create 创建);*       若字体已绑定到控件(如 label、textarea),需先销毁控件或解除字体绑定,再释放字体,否则会导致控件文本显示异常(乱码、空白)*/
void lv_freetype_font_delete(lv_font_t *font);/*** 为 LVGL 控件设置文本字体(通用接口,支持 FreeType 字体、LVGL 原生字体)* @param obj 目标控件(支持文本显示的控件,如 lv_label、lv_textarea、lv_button、lv_menu 等,不可为 NULL)* @param value 要设置的字体对象(lv_font_t*,可为 FreeType 创建的字体或 LVGL 原生字体,如 &lv_font_montserrat_16;NULL 时使用 LVGL 默认字体)* @param selector 样式选择器(指定控件状态或全局样式,常用 LV_STYLE_SELECTOR_ALL=应用于所有状态;也可指定单个状态,如 LV_STATE_PRESSED=仅按下状态)* @return 无返回值* @note 控件创建后可随时调用,实时更新文本字体;*       字体大小需与控件尺寸匹配,避免文本溢出或显示不全;*       若设置 FreeType 字体,需确保字体对象未被提前释放*/
void lv_obj_set_style_text_font(lv_obj_t *obj, const lv_font_t *value, lv_style_selector_t selector);/*** 为 LVGL 控件设置文本颜色(控制文本显示的颜色)* @param obj 目标控件(支持文本显示的控件,不可为 NULL)* @param value 文本颜色(lv_color_t 类型,可通过 lv_color_hex(0xRRGGBB) 快速创建,如 0x000000=黑色、0xFFFFFF=白色、0xFF0000=红色)* @param selector 样式选择器(LV_STYLE_SELECTOR_ALL=所有状态生效;或指定单个状态,如 LV_STATE_DISABLED=仅禁用状态)* @return 无返回值* @note 颜色值遵循 RGB888 格式(0xRRGGBB 中 RR=红色通道、GG=绿色通道、BB=蓝色通道,取值 0~255);可为不同状态设置不同颜色,如默认状态黑色、按下状态红色*/
void lv_obj_set_style_text_color(lv_obj_t *obj, lv_color_t value, lv_style_selector_t selector);/*** 为 LVGL 控件设置文本对齐方式(适用于单行/多行文本)* @param obj 目标控件(支持文本显示的控件,不可为 NULL,如标签、输入框)* @param value 对齐方式(枚举类型:LV_TEXT_ALIGN_LEFT=左对齐(默认);LV_TEXT_ALIGN_CENTER=居中对齐;LV_TEXT_ALIGN_RIGHT=右对齐;LV_TEXT_ALIGN_JUSTIFY=两端对齐(仅多行文本生效))* @param selector 样式选择器(LV_STYLE_SELECTOR_ALL=所有状态生效;或指定单个状态)* @return 无返回值* @note 对齐基准为控件的「内容区域」,而非整个控件尺寸;* 单行文本推荐使用左/中/右对齐,多行文本可使用两端对齐*/
void lv_obj_set_style_text_align(lv_obj_t *obj, lv_text_align_t value, lv_style_selector_t selector);/*** 为 LVGL 控件设置文本行间距(仅多行文本生效)* @param obj 目标控件(支持多行文本的控件,如 lv_label、lv_textarea,不可为 NULL)* @param value 行间距大小(单位:像素,可正可负,建议设字体大小的 1/2~1 倍,如 24px 字体设 12=12px 行间距;设 0=默认行间距)* @param selector 样式选择器(LV_STYLE_SELECTOR_ALL=所有状态生效;或指定单个状态)* @return 无返回值* @note 单行文本设置行间距无效果;*       行间距过大会增加文本区域占用空间,需预留足够的控件尺寸;*       负行间距可能导致文本重叠,不推荐使用*/
void lv_obj_set_style_text_line_space(lv_obj_t *obj, int32_t value, lv_style_selector_t selector);/*** 为输入框控件(lv_textarea)设置占位提示文本(无输入内容时显示的提示信息)* @param obj 输入框控件对象(lv_obj_t*,由 lv_textarea_create 创建,不可为 NULL)* @param txt 占位提示文本(支持 UTF-8 编码,可为中文,如"请输入姓名...";不可为 NULL,空字符串""=隐藏占位提示)* @return 无返回值* @note   占位文本的字体、颜色、对齐方式需通过 lv_obj_set_style_* 接口单独设置(默认继承控件的文本样式);*         输入框有内容时占位文本自动隐藏,内容清空后重新显示;*         若需支持中文占位提示,需为输入框设置支持中文的字体(如 FreeType 创建的 TTF 字体)*/
void lv_textarea_set_placeholder_text(lv_obj_t *obj, const char *txt);
/*** 设置标签控件的显示文本(支持绑定FreeType字体后显示中文等字符)* @param label 标签控件对象(lv_obj_t*,由lv_label_create创建,不可为NULL)* @param text 要显示的文本内容(不可为NULL,支持字符串常量、动态分配字符串,如中文"你好"、英文"Hello")* @return 无返回值* @note 文本长度需不超过控件尺寸+字体限制,否则会被截断(可通过lv_label_set_long_mode设置超长处理方式);*       文本编码需与字体支持的编码一致(默认UTF-8)*/
void lv_label_set_text(lv_obj_t *label, const char *text);

总结

  • 静态字体(如 simkai_26.c)适合固定文本(登录、注册),占用 FLASH 小;
  • FreeType 动态加载适合动态文本(输入、新闻),支持任意汉字和样式,灵活但需占用更多 RAM/FLASH;
  • 嵌入式优先「源码集成」FreeType,UNIX / 开发板可「编译安装」,配置和 API 需严格遵循 LVGL 官方规范。

输入框(lv_textarea)与键盘(lv_keyboard):联动实现输入

输入框用于账号 / 密码输入,需与键盘联动,核心是 “关联输入目标” 与 “控制键盘显隐”。

常用函数接口解析:

输入框(lv_textarea)核心接口(含 FreeType 中文支持)

/*** 创建输入框控件对象(用于账号、密码、文本等输入场景)* @param parent 父控件对象(lv_obj_t*,可为屏幕、容器等,不可为NULL)* @return 成功创建的输入框控件对象(lv_obj_t*),创建失败返回NULL* @note 需通过lv_obj_set_size、lv_obj_align等接口补充设置尺寸和位置;*       初始状态无占位文本、默认可编辑,需手动配置相关功能属性*/
lv_obj_t *lv_textarea_create(lv_obj_t *parent);/*** 设置输入框的占位提示文本(无输入时显示,支持中文)* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param txt 占位提示文本内容(const char*,不可为NULL,支持UTF-8编码,如"请输入账号")* @return 无返回值* @note 输入内容后占位文本自动隐藏,清空输入后重新显示;*       文本长度需适配输入框尺寸,过长会被截断,建议简洁提示*/
void lv_textarea_set_placeholder_text(lv_obj_t *obj, const char *txt);/*** 启用或禁用输入框的密码显示模式* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param en 启用状态(bool类型,true=启用密码模式,false=禁用密码模式)* @return 无返回值* @note 启用后输入字符以圆点/星号形式显示,保护隐私;*       禁用后正常显示输入内容,适用于普通文本输入*/
void lv_textarea_set_password_mode(lv_obj_t *obj, bool en);/*** 获取输入框中已输入的文本内容* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @return 输入文本的只读指针(const char*),无输入时返回空字符串* @note 返回指针指向输入框内部缓存,无需手动free,不可修改;*       输入框销毁后指针立即失效,不可继续使用*/
const char *lv_textarea_get_text(lv_obj_t *obj);/*** 直接设置输入框的显示文本(覆盖原有内容,支持中文)* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param text 要设置的文本内容(const char*,不可为NULL,支持UTF-8编码,如"管理员")* @return 无返回值* @note 文本长度不能超过lv_textarea_set_max_length设置的限制(无限制除外);*       设置后占位文本自动隐藏,光标定位到文本末尾*/
void lv_textarea_set_text(lv_obj_t *obj, const char *text);/*** 设置输入框允许输入的最大文本长度* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param len 最大输入长度(uint32_t类型,0表示无长度限制)* @return 无返回值* @note 超过最大长度后,后续输入字符将被忽略;*       已输入文本超过最大长度时,不会自动截断,需手动处理*       lv_textarea_set_text(obj, "") 设空字符串 可清空文本框内容*/
void lv_textarea_set_max_length(lv_obj_t *obj, uint32_t len);/*** 设置输入框允许输入的字符集(仅指定字符可输入)* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param chars 允许输入的字符集合(const char*,不可为NULL,如"0123456789")* @return 无返回值* @note 字符集支持UTF-8编码,可包含中文、数字、字母等任意字符;*       非字符集中的按键操作,输入框不会响应,适用于格式限制场景*/
void lv_textarea_set_accepted_chars(lv_obj_t *obj, const char *chars);/*** 获取输入框的占位提示文本* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @return 占位提示文本的只读指针(const char*),未设置时返回NULL* @note 返回指针指向输入框内部缓存,不可修改;*       输入框销毁后指针立即失效*/
const char *lv_textarea_get_placeholder_text(lv_obj_t *obj);/*** 获取输入框中光标的当前位置* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @return 光标位置索引(uint32_t类型,从0开始,等于文本长度时在末尾)* @note 可用于判断光标是否在文本开头、中间或末尾;*       无输入文本时,光标位置为0*/
uint32_t lv_textarea_get_cursor_pos(const lv_obj_t *obj);/*** 设置输入框中光标的位置* @param obj 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @param pos 目标光标位置索引(uint32_t类型)* @return 无返回值* @note pos超过当前文本长度时,光标自动定位到文本末尾;*       pos超出无符号范围时,光标定位到起始位置(0)*/
void lv_textarea_set_cursor_pos(lv_obj_t *obj, uint32_t pos);

键盘(lv_keyboard)核心接口(含联动输入框)

/*** 创建键盘控件对象(用于与输入框联动,支持多种输入模式)* @param parent 父控件对象(lv_obj_t*,通常为屏幕,确保层级最上层,不可为NULL)* @return 成功创建的键盘控件对象(lv_obj_t*),创建失败返回NULL* @note 建议设置尺寸为屏幕宽度,底部对齐(lv_align_bot_mid);*       初始状态建议隐藏(添加LV_OBJ_FLAG_HIDDEN),通过输入框聚焦事件显示*/
lv_obj_t *lv_keyboard_create(lv_obj_t *parent);/*** 关联键盘与输入框(键盘输入内容自动写入关联输入框)* @param kb 键盘控件对象(lv_obj_t*,由lv_keyboard_create创建,不可为NULL)* @param ta 输入框控件对象(lv_obj_t*,由lv_textarea_create创建,不可为NULL)* @return 无返回值* @note 同一时间建议只关联一个输入框,切换输入框时需重新调用;*       关联后可根据输入框需求调整键盘模式(如数字输入框对应数字模式)*/
void lv_keyboard_set_textarea(lv_obj_t *kb, lv_obj_t *ta);/*** 设置键盘的输入模式(文本/数字/符号等)* @param kb 键盘控件对象(lv_obj_t*,由lv_keyboard_create创建,不可为NULL)* @param mode 输入模式枚举(lv_keyboard_mode_t类型,如小写文本、数字等)* @return 无返回值* @note 模式变更后,键盘按键布局自动适配对应模式;*       需使用LVGL定义的合法模式常量(如LV_KEYBOARD_MODE_TEXT_LOWER)*/
void lv_keyboard_set_mode(lv_obj_t *kb, lv_keyboard_mode_t mode);/*** 获取键盘当前关联的输入框对象* @param kb 键盘控件对象(lv_obj_t*,由lv_keyboard_create创建,不可为NULL)* @return 当前关联的输入框对象(lv_obj_t*),未关联时返回NULL* @note 返回的输入框对象需确保未被销毁,否则操作会导致异常;*       可用于判断键盘是否已关联有效输入框*/
lv_obj_t *lv_keyboard_get_textarea(const lv_obj_t *kb);/*** 获取键盘当前的输入模式* @param kb 键盘控件对象(lv_obj_t*,由lv_keyboard_create创建,不可为NULL)* @return 当前输入模式枚举值(lv_keyboard_mode_t类型)* @note 可通过返回值判断键盘支持的输入类型(文本/数字等);*       结合输入框需求动态切换模式,提升输入体验*/
lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t *kb);

实战:登录窗口(输入框 + 键盘 + 中文)

#include "lvgl/lvgl.h"
#include <string.h>  // 字符串处理依赖LV_FONT_DECLARE(simkai_26);  // 中文字库(26号)
static lv_obj_t *g_kb = NULL;          // 全局键盘对象
static lv_obj_t *g_login_tip = NULL;   // 全局提示标签指针(避免查找接口)// 封装账号/密码输入框指针(传递给回调)
typedef struct {lv_obj_t *ta_user;lv_obj_t *ta_pwd;
} login_input_t;/*** 定时器回调:跳转主页(LVGL 9.2 标准接口)*/
static void home_jump_cb(lv_timer_t *t) {lv_obj_t *home = lv_obj_create(NULL);  lv_scr_load(home);  // 加载新屏幕// 主页背景色+示例文本lv_obj_set_style_bg_color(home, lv_color_hex(0xFFFFFF), LV_PART_MAIN);lv_obj_t *home_label = lv_label_create(home);lv_label_set_text(home_label, "Welcome to the homepage!");lv_obj_center(home_label);lv_timer_del(t);
}/*** 输入框聚焦/失焦:控制键盘显隐*/
static void ta_focus_cb(lv_event_t *e) {lv_obj_t *ta = lv_event_get_target(e);if (lv_event_get_code(e) == LV_EVENT_FOCUSED) {lv_keyboard_set_textarea(g_kb, ta);lv_obj_remove_flag(g_kb, LV_OBJ_FLAG_HIDDEN);} else if (lv_event_get_code(e) == LV_EVENT_DEFOCUSED) {lv_obj_add_flag(g_kb, LV_OBJ_FLAG_HIDDEN);}
}/*** 登录按钮回调:验证账号密码*/
static void login_btn_cb(lv_event_t *e) {// 从用户数据获取输入框指针(无 lv_obj_get_next_sibling)login_input_t *input = lv_event_get_user_data(e);const char *user = lv_textarea_get_text(input->ta_user);const char *pwd = lv_textarea_get_text(input->ta_pwd);// 删除旧提示标签(全局指针直接操作)if (g_login_tip) {lv_obj_del(g_login_tip);g_login_tip = NULL;}// 创建新提示标签g_login_tip = lv_label_create(lv_scr_act());// lv_obj_set_style_text_font(g_login_tip, &simkai_26, LV_PART_MAIN);lv_obj_align(g_login_tip, LV_ALIGN_CENTER, 0, -150);if (strlen(user) == 0 || strlen(pwd) == 0) {lv_label_set_text(g_login_tip, "Account/password cannot be empty!");lv_obj_set_style_text_color(g_login_tip, lv_color_hex(0xFF0000), LV_PART_MAIN);} else if (strcmp(user, "admin") == 0 && strcmp(pwd, "123456") == 0) {lv_label_set_text(g_login_tip, "Login successful!");lv_obj_set_style_text_color(g_login_tip, lv_color_hex(0x00FF00), LV_PART_MAIN);// 1秒后跳主页lv_timer_create(home_jump_cb, 1000, NULL);} else {lv_label_set_text(g_login_tip, "Account/password incorrect!");lv_obj_set_style_text_color(g_login_tip, lv_color_hex(0xFF0000), LV_PART_MAIN);// 清空密码框(LVGL 9.2 标准方式)lv_textarea_set_text(input->ta_pwd, "");}
}/*** 创建登录窗口*/
login_input_t input;
void login_ui(void) {lv_obj_t *scr = lv_scr_act();lv_obj_set_style_bg_color(scr, lv_color_hex(0xF5F5F5), LV_PART_MAIN);// 账号输入框lv_obj_t *ta_user = lv_textarea_create(scr);lv_obj_set_size(ta_user, 300, 50);lv_obj_align(ta_user, LV_ALIGN_TOP_MID, 0, 100);lv_textarea_set_placeholder_text(ta_user, "Please enter your account");lv_textarea_set_max_length(ta_user, 16);// 密码输入框(密码模式)lv_obj_t *ta_pwd = lv_textarea_create(scr);lv_obj_set_size(ta_pwd, 300, 50);lv_obj_align(ta_pwd, LV_ALIGN_TOP_MID, 0, 200);lv_textarea_set_placeholder_text(ta_pwd, "Please enter the password");lv_textarea_set_password_mode(ta_pwd, true);lv_textarea_set_max_length(ta_pwd, 16);// 封装输入框指针(修复:去掉 static,避免非const初始化错误)input.ta_user = ta_user;input.ta_pwd = ta_pwd;// 登录按钮lv_obj_t *btn_login = lv_btn_create(scr);lv_obj_set_size(btn_login, 100, 70);lv_obj_align(btn_login, LV_ALIGN_TOP_MID, 0, 300);lv_obj_t *label_login = lv_label_create(btn_login);lv_label_set_text(label_login, "登录");lv_obj_set_style_text_font(label_login, &simkai_26, LV_PART_MAIN);lv_obj_center(label_login);// 键盘(默认隐藏,底部显示)g_kb = lv_keyboard_create(scr);lv_obj_set_size(g_kb, lv_obj_get_width(scr), 250);lv_obj_align(g_kb, LV_ALIGN_BOTTOM_MID, 0, 0);lv_obj_add_flag(g_kb, LV_OBJ_FLAG_HIDDEN);lv_keyboard_set_mode(g_kb, LV_KEYBOARD_MODE_TEXT_LOWER);// 绑定事件(传递输入框封装指针)lv_obj_add_event_cb(ta_user, ta_focus_cb, LV_EVENT_ALL , NULL);lv_obj_add_event_cb(ta_pwd, ta_focus_cb, LV_EVENT_ALL , NULL);lv_obj_add_event_cb(btn_login, login_btn_cb, LV_EVENT_CLICKED, &input);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/961117.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年比较好的钢塑课桌椅优质厂家推荐榜单

2025年优质钢塑课桌椅厂家推荐榜单:专业解析与采购指南行业背景与市场趋势随着教育现代化进程加速和校园设施升级需求激增,钢塑课桌椅行业正迎来前所未有的发展机遇。据中国教育装备行业协会最新数据显示,2024年我国…

2025年靠谱的服装激光打孔机厂家最新实力排行

2025年靠谱的服装激光打孔机厂家最新实力排行行业背景与市场趋势随着服装行业对精细化、个性化生产需求的不断提升,激光打孔技术凭借其高精度、高效率、无接触加工等优势,正逐渐成为服装制造领域的重要工艺手段。根据…

AIGC|数字人平台技术创新与选择指南 - 二当家

数字人技术:开启未来交互新纪元 从概念到落地,数字人技术如何重塑产业生态? 解密数字人技术内核:像衍科技如何以创新驱动行业变革? 第一部分:数字人是什么? 数字人,是依托人工智能、计算机图形学、自然语言处理…

【10月25日证书】PostgreSQL管理员认证工信人才官网可查

恭喜2025年10月18日参加工信部人才交流中心PostgreSQL管理员认证考试的各位同学,可以查询下载电子证书啦,电子版的证书在工信部人才交流中心官网可查,或者联系咨询老师直接发给你! 工信部人才交流中心PostgreSQL证…

ONNX模型文件

ONNX(Open Neural Network Exchange,开放神经网络交换)模型文件是一种开放格式,用于表示机器学习和深度学习模型。它充当不同 AI 框架之间的通用“桥梁”或中间表示层。 主要用途和特点互操作性(Interoperability…

ESXi 6.7安装教程

1、插入U盘进入ESXi安装程序 2、ESXi启动安全界面 3、Enter继续 4、F11接受并继续 5、选择ESXi安装到哪个硬盘,【ESC------>取消、F1------>详情、F5------>刷新硬盘、Enter------>继续安装】 6、选…

2025年靠谱的重型纸箱最新TOP厂家排名

2025年靠谱的重型纸箱最新TOP厂家排名行业背景与市场趋势随着全球制造业的持续发展和电商物流的蓬勃兴起,重型纸箱作为工业包装的核心产品,市场需求呈现稳定增长态势。根据中国包装联合会最新发布的《2024-2025中国包…

无法处理文件 Launcher.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记。

解决方法 重新生成 .resx 文件 1.备份 Launcher.resx 的内容(用文本编辑器打开,它是 XML 格式)。 2.删除原文件,然后在 Visual Studio 中: 右键项目 → 添加 → 新建项 → 资源文件 (.resx)。 重新编译。本文来自…

MATLAB中PCNN输出域改进及其在彩色图像增强中的应用

脉冲耦合神经网络(PCNN)的输出域改进可通过动态阈值调整、多尺度分解和颜色空间优化实现,结合MATLAB的矩阵运算特性,可显著提升彩色图像增强的效果。一、PCNN输出域改进策略动态阈值优化传统问题:固定阈值导致低亮…

前端环境搭建,保姆式教学 - 详解

前端环境搭建,保姆式教学 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&q…

2025 年 11 月建筑资质办理/转让/新办/收购/代办厂家推荐排行榜,消防维保/总包/劳务/地基基础工程/电子与智能化工程/消防设施工程/防水防腐保温工程资质公司推荐

2025 年 11 月建筑资质办理/转让/新办/收购/代办厂家推荐排行榜,消防维保/总包/劳务/地基基础工程/电子与智能化工程/消防设施工程/防水防腐保温工程资质公司推荐 一、行业背景与发展趋势 建筑资质行业作为工程建设领…

2025 年 11 月地坪厂家推荐排行榜,环氧地坪漆,聚氨酯地坪,固化耐磨地坪,防腐地坪,室外路面防滑地坪,运动地面,PVC塑胶地板,魔石地坪公司推荐

2025年11月地坪厂家推荐排行榜:专业选购指南 行业背景与发展趋势 地坪材料行业作为建筑装饰领域的重要组成部分,近年来呈现出快速发展的态势。随着工业4.0时代的到来,现代化厂房、商业空间、运动场馆等对地坪材料的…

2025年评价高的耐甲酸涂料TOP实力厂家推荐榜

2025年评价高的耐甲酸涂料TOP实力厂家推荐榜行业背景与市场趋势耐甲酸涂料作为工业防护领域的关键材料,近年来随着化工、制药、食品加工等行业的快速发展,市场需求持续增长。根据中国涂料工业协会最新发布的《2024-2…

2025 年 11 月隔热条厂家推荐排行榜,尼龙隔热条,PA66尼龙隔热条,建筑用隔热条,断桥铝门窗隔热条,门窗幕墙阳光房隔热条公司推荐

2025年11月隔热条厂家推荐排行榜:专业解析尼龙隔热条行业格局 行业背景与发展现状 随着建筑节能要求的不断提高和绿色建筑理念的深入推广,隔热条作为建筑节能的关键材料,在门窗幕墙系统中的重要性日益凸显。特别是在…

一次通过Wireshark排查DLP系统因IP变动运行异常的经历

一次通过Wireshark排查DLP系统因IP变动运行异常的经历公司曾使用亿赛通对文件进行加密,后更换为 IP-guard。为实现无需安装亿赛通客户端即可读取历史加密文件,供应商部署了一台服务器,模拟客户端进行解密。该服务与…

2025年杭州公司律师权威推荐榜单:离婚律师/婚姻律师服务机构精选

随着杭州数字经济与实体经济的深度融合,企业对专业法律服务的需求呈现显著增长态势。据行业统计数据显示,2024年杭州企业法律顾问服务市场规模同比增长18.5%,其中数字经济企业法律服务需求占比达35%,制造业企业法律…

2025年热门的反弹器厂家推荐及选购指南

2025年热门的反弹器厂家推荐及选购指南行业背景与市场趋势随着全屋定制家居市场的持续升温,反弹器作为现代家居五金的核心组件,正迎来前所未有的发展机遇。据中国五金制品协会最新数据显示,2024年国内反弹器市场规模…

2025年食品厂聚丙烯酰胺生产厂家权威推荐榜单:养殖场聚丙烯酰胺/聚丙烯酰胺阴粉/聚丙烯酰胺分子量源头厂家精选

在食品安全标准日益严格与食品工业废水处理要求持续提升的背景下,食品厂聚丙烯酰胺作为水处理关键药剂,其质量与适用性直接影响处理效果与合规性。根据QYResearch报告数据显示,2031年全球聚丙烯酰胺聚合物市场销售额…

MyBatis的配置文件中定义类型别名(type aliases)的技巧

在MyBatis中,类型别名(Type Aliases)是为JAVA类型设置一个短的名字,它只是用于减少配置复杂性和增强可读性。当配置SQL映射的时候,你可以使用这个别名代替JAVA类型的全限定名(fully qualified class name)。 通常…

vbs脚本,批量将word文件转为pdf文件

以下是将word文件批量转为pdf文件的vbs脚本:点击查看代码 Set wdapp = CreateObject("word.application") wdapp.Visible = False 隐藏Word应用程序For i = 0 To WScript.Arguments.Count - 1Set doc = wd…