4、核心控件详解(一):标签(Label)、按钮(Button)、文本框(Text Area)的使用与属性配置

各位同学,欢迎来到第四章。

前面三章我们把 LVGL 的底层机制、对象树、事件传递都捋了一遍。说实话,那些是内功心法。从今天开始,咱们要开始练具体招式了。

这一章我挑三个最常用的控件来讲:标签(Label)按钮(Button)文本框(Text Area)。这三个控件,你想想看,几乎每个嵌入式界面都离不开。显示文字、触发操作、输入内容——人机交互的三大基本动作,全被它们包了。

4.1 标签(Label)—— 不只是显示文字那么简单

标签控件,说白了就是用来显示文本的。但如果你以为它只是「把字符串怼到屏幕上」,那就太小看它了。

4.1.1 创建与基本属性

创建一个标签,代码非常简单:

lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello, LVGL!");

嗯,两行搞定。但这里有个细节——父对象是谁?我习惯把标签放在一个容器里,而不是直接放在屏幕上。为什么?因为后面你要做界面布局,容器可以帮你统一管理位置和大小。

标签有几个核心属性,我列个表给你看:

属性 API 函数 说明
文本内容 lv_label_set_text() 设置显示的字符串
文本颜色 lv_obj_set_style_text_color() 支持 16 位或 32 位颜色值
字体大小 lv_obj_set_style_text_font() 可以切换内置字体或自定义字体
对齐方式 lv_label_set_long_mode() 控制文字超出时的行为
文本滚动 lv_label_set_scroll() 文字太长时自动滚动显示

4.1.2 长文本处理模式

我在项目中遇到过一个问题:标签里的文字太长,超出了控件边界。结果文字被截断了,用户看不到完整信息。

LVGL 提供了几种长文本处理模式,用 lv_label_set_long_mode() 来设置:

  • LV_LABEL_LONG_WRAP:自动换行。这是最常用的模式,文字超出宽度就换到下一行。
  • LV_LABEL_LONG_DOT:超出部分显示省略号。适合单行显示的场景。
  • LV_LABEL_LONG_SCROLL:文字滚动显示。适合跑马灯效果。
  • LV_LABEL_LONG_CLIP:直接裁剪。不推荐,除非你确定文字不会超。
我的建议:如果你做的是信息展示类界面,比如温湿度数值,用 LV_LABEL_LONG_DOT 比较稳妥。如果做的是多行文本阅读,用 LV_LABEL_LONG_WRAP

4.1.3 文本重新着色(Text Recolor)

这个功能挺有意思。你可以在字符串里嵌入颜色标记,让同一段文字显示不同颜色。

lv_label_set_recolor(label, true);
lv_label_set_text(label, "#FF0000 红色# #00FF00 绿色# 默认颜色");

注意,这个功能默认是关闭的。你需要手动开启。我曾经在一个仪表盘项目里用过这个功能,把报警数值标红,正常数值标绿,效果非常直观。

4.2 按钮(Button)—— 交互的起点

按钮是用户触发动作的主要方式。你想想看,点击、长按、释放——这些事件都跟按钮有关。

4.2.1 创建与样式

lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 120, 50);
lv_obj_center(btn);

创建按钮本身很简单。但真正让按钮「好看又好用」的,是它的样式配置。

按钮的样式分为几个状态:

  • 默认状态:按钮没被按下时的样子
  • 按下状态:用户手指或鼠标按下时
  • 禁用状态:按钮不可操作时
  • 聚焦状态:按钮获得焦点时(键盘或遥控器操作)

我习惯给每个状态都配不同的颜色和阴影。比如:

/* 默认状态:蓝色背景 */
lv_obj_set_style_bg_color(btn, lv_color_hex(0x2196F3), LV_STATE_DEFAULT);
/* 按下状态:深蓝色背景 */
lv_obj_set_style_bg_color(btn, lv_color_hex(0x1976D2), LV_STATE_PRESSED);
关键点:样式配置的第三个参数是状态掩码。你可以用 LV_STATE_DEFAULTLV_STATE_PRESSEDLV_STATE_DISABLED 等。如果不指定状态,默认只影响 LV_STATE_DEFAULT

4.2.2 按钮上的文字

按钮上通常要显示文字。你可以创建一个标签作为按钮的子对象:

lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "确认");
lv_obj_center(label);

嗯,这里有个小技巧:标签的父对象是按钮。这样标签会跟随按钮移动,而且按钮的点击事件会自动传递给标签。

4.2.3 事件处理

按钮最核心的就是事件。我常用的写法是:

lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

static void btn_event_cb(lv_event_t *e) {
    LV_LOG_USER("按钮被点击了!");
    /* 在这里执行你的业务逻辑 */
}

注意,我用的是 LV_EVENT_CLICKED 而不是 LV_EVENT_PRESSED。为什么?因为 CLICKED 是在按下并释放后才触发,更符合用户对「点击」的认知。如果你用 PRESSED,用户刚碰到按钮就触发了,体验不好。

避坑指南:我曾经在一个项目中,用 LV_EVENT_PRESSED 来处理按钮。结果用户手指在按钮上滑动时,事件被反复触发。后来改成 LV_EVENT_CLICKED 才解决。记住:点击 = 按下 + 释放

4.3 文本框(Text Area)—— 让用户输入内容

文本框是这三个控件里最复杂的。它允许用户输入和编辑文本,支持光标、选中、密码模式等功能。

4.3.1 创建与基本配置

lv_obj_t *ta = lv_textarea_create(lv_scr_act());
lv_textarea_set_placeholder_text(ta, "请输入用户名...");
lv_textarea_set_max_length(ta, 20);

创建文本框后,我建议你立刻做两件事:

  1. 设置占位符文本:告诉用户这里该输入什么
  2. 设置最大长度:防止用户输入过长内容导致缓冲区溢出

4.3.2 核心属性配置

功能 API 函数 说明
设置文本 lv_textarea_set_text() 直接替换文本框内容
获取文本 lv_textarea_get_text() 返回当前文本的指针
密码模式 lv_textarea_set_password_mode() 输入内容显示为圆点
光标显示 lv_textarea_set_cursor_show() 控制光标是否可见
单行/多行 lv_textarea_set_one_line() true 为单行,false 为多行
选中范围 lv_textarea_set_cursor_pos() 设置光标位置,配合选中操作

4.3.3 密码模式与键盘

密码模式是文本框的一个典型应用。开启方式很简单:

lv_textarea_set_password_mode(ta, true);
lv_textarea_set_password_bullet(ta, '*');  /* 自定义显示字符 */

但这里有个坑:密码模式下,文本框的内容仍然是明文存储的。LVGL 只是把显示内容替换成了圆点。所以如果你要传输或存储密码,记得自己加密。

另外,文本框通常需要配合键盘使用。LVGL 内置了一个简单的键盘控件:

lv_obj_t *kb = lv_keyboard_create(lv_scr_act());
lv_keyboard_set_textarea(kb, ta);

这样键盘和文本框就关联起来了。用户点击键盘上的按键,文本会自动输入到文本框里。

我的经验:在嵌入式设备上,如果屏幕尺寸有限,我建议把键盘做成弹出式的。平时隐藏,点击文本框时才显示。这样能节省宝贵的屏幕空间。

4.3.4 事件监听

文本框的事件比按钮丰富。常用的有:

  • LV_EVENT_VALUE_CHANGED:文本内容发生变化时触发
  • LV_EVENT_READY:用户按下「完成」或「确认」键时触发
  • LV_EVENT_CANCEL:用户取消输入时触发

我一般会在 LV_EVENT_VALUE_CHANGED 里做实时校验。比如检查输入是否为数字、长度是否合规等。

lv_obj_add_event_cb(ta, ta_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

static void ta_event_cb(lv_event_t *e) {
    lv_obj_t *ta = lv_event_get_target(e);
    const char *text = lv_textarea_get_text(ta);
    if (strlen(text) > 10) {
        LV_LOG_USER("输入内容过长!");
    }
}

4.4 三个控件的组合使用

在实际项目中,这三个控件经常一起出现。比如一个登录界面:

  • Label 显示「用户名」和「密码」提示
  • Text Area 让用户输入账号和密码
  • Button 触发登录操作

我建议你从今天开始,试着用这三个控件搭建一个小界面。不用太复杂,一个登录框就行。做完之后,你会对 LVGL 的控件体系有更直观的理解。

本章小结:
  • Label 不只是显示文字,还要考虑长文本处理和颜色标记
  • Button 的样式要区分不同状态,事件用 CLICKED 更合理
  • Text Area 要设置占位符和最大长度,密码模式只是显示上的伪装

下一章,我们会继续深入核心控件,聊聊滑块(Slider)、进度条(Bar)和开关(Switch)。这些控件在参数调节和状态显示中非常实用。到时候见。