公司动态

玩转LVGL Arc控件:从零打造动态仪表盘

📅 2026/7/16 16:38:32
玩转LVGL Arc控件:从零打造动态仪表盘
1. 初识LVGL Arc控件仪表盘的灵魂部件第一次接触LVGL的Arc控件时我正为一个智能家居项目设计温控器界面。当时需要展示温度调节范围传统的滑块控件显得太呆板而圆形仪表盘才是理想选择。Arc控件完美解决了这个问题——它就像汽车仪表盘上的速度指针用弧线运动直观展示数据变化。Arc控件由三个核心部分组成背景弧LV_PART_MAIN相当于仪表盘的刻度盘我用它显示0-40℃的温度范围指示器弧LV_PART_INDICATOR动态变化的彩色弧线实时反映当前温度旋钮LV_PART_KNOB弧线末端的圆形手柄支持触摸拖动调节在STM32F4开发板上创建一个基础Arc控件只需要几行代码lv_obj_t *arc lv_arc_create(lv_scr_act()); lv_arc_set_bg_angles(arc, 0, 270); // 设置270度弧形范围 lv_arc_set_range(arc, 0, 40); // 对应0-40℃ lv_obj_set_size(arc, 200, 200); // 设置控件大小2. 深度解析Arc控件API2.1 角度控制仪表盘的刻度艺术Arc控件的角度系统很特别0度指向正右方3点钟方向角度值顺时针增加。在制作车速表时我通常设置背景弧从130度到410度即230度范围这样能营造出经典的速度表视觉效果。几个关键API// 设置背景弧起止角度推荐 lv_arc_set_bg_angles(arc, 130, 410); // 单独设置起止角度特殊场景使用 lv_arc_set_bg_start_angle(arc, 130); lv_arc_set_bg_end_angle(arc, 410);实测发现当需要动态修改角度时lv_arc_set_bg_angles()比分开调用的性能更好因为它只触发一次重绘。2.2 旋转技巧打破常规布局默认0度位置可能不符合设计需求。通过lv_arc_set_rotation()我成功将一个Arc旋转90度创造出顶部起始的扇形菜单。比如lv_arc_set_rotation(arc, 90); // 将0度位置旋转到顶部2.3 值与范围数据映射的核心在智能电表项目中我需要将0-100A的电流映射到弧线范围。LVGL的值范围映射非常实用lv_arc_set_range(arc, 0, 100); // 设置物理量范围 lv_arc_set_value(arc, 35); // 设置当前值自动计算角度当值改变时指示器弧会自动更新位置。结合下面的事件处理可以构建完整的交互体验。3. 打造动态仪表盘实战3.1 基础仪表盘实现最近为无人机飞控设计的姿态指示器就充分利用了Arc控件。关键实现步骤创建双层Arc控件模拟航空仪表// 外层背景弧灰色刻度盘 lv_obj_t *bg_arc lv_arc_create(lv_scr_act()); lv_arc_set_bg_angles(bg_arc, 150, 390); lv_obj_set_style_arc_color(bg_arc, lv_color_hex(0xCCCCCC), LV_PART_MAIN); // 内层指示器弧红色指针 lv_obj_t *indicator lv_arc_create(lv_scr_act()); lv_arc_set_bg_angles(indicator, 150, 390); lv_obj_set_style_arc_color(indicator, lv_color_hex(0xFF0000), LV_PART_INDICATOR);添加旋钮样式增强可视性lv_obj_set_style_bg_color(arc, lv_color_hex(0xFF0000), LV_PART_KNOB); lv_obj_set_style_pad_all(arc, 5, LV_PART_KNOB); // 旋钮比弧线宽5像素3.2 动态数据绑定通过定时器实现实时数据更新void timer_cb(lv_timer_t *timer) { int rpm get_motor_rpm(); // 获取实时转速 lv_arc_set_value(arc, rpm); // 更新Arc显示 // 危险转速红色警示 if(rpm 8000) { lv_obj_set_style_arc_color(arc, lv_color_hex(0xFF0000), LV_PART_INDICATOR); } } lv_timer_create(timer_cb, 100, NULL); // 每100ms更新3.3 交互优化技巧在工业HMI项目中我发现直接拖动弧线有时不够精确。通过以下改进提升了操作体验增加点击区域lv_obj_set_ext_click_area(arc, 15); // 将点击区域向外扩展15像素调整变化速率lv_arc_set_change_rate(arc, 60); // 限制变化速率为60度/秒添加触觉反馈static void arc_event_cb(lv_event_t *e) { if(lv_event_get_code(e) LV_EVENT_VALUE_CHANGED) { vibrate(50); // 触发50ms震动 } } lv_obj_add_event_cb(arc, arc_event_cb, LV_EVENT_VALUE_CHANGED, NULL);4. 高级样式与特效4.1 渐变效果实现通过修改样式属性可以创建更专业的视觉效果// 创建渐变色样式 static lv_style_t style_indicator; lv_style_init(style_indicator); lv_style_set_arc_color(style_indicator, lv_color_hex(0x00FF00)); lv_style_set_arc_opa(style_indicator, LV_OPA_70); lv_style_set_arc_width(style_indicator, 15); // 应用到指示器部分 lv_obj_add_style(arc, style_indicator, LV_PART_INDICATOR);4.2 创意仪表盘设计结合LVGL的其他控件可以设计出丰富多样的仪表盘速度表转速表组合// 速度表 lv_obj_t *speed_arc lv_arc_create(lv_scr_act()); lv_arc_set_bg_angles(speed_arc, 120, 420); lv_obj_set_style_arc_width(speed_arc, 20, LV_PART_MAIN); // 转速表内圈 lv_obj_t *rpm_arc lv_arc_create(lv_scr_act()); lv_arc_set_bg_angles(rpm_arc, 120, 420); lv_obj_set_style_arc_width(rpm_arc, 10, LV_PART_MAIN); lv_obj_align(rpm_arc, LV_ALIGN_CENTER, 0, 0);带数字显示的混合仪表// 添加数字标签 lv_obj_t *label lv_label_create(lv_scr_act()); lv_obj_align_to(label, arc, LV_ALIGN_CENTER, 0, 0); lv_label_set_text_fmt(label, %d, lv_arc_get_value(arc)); // 值改变时更新标签 lv_obj_add_event_cb(arc, [](lv_event_t *e) { lv_label_set_text_fmt(label, %d, lv_arc_get_value(arc)); }, LV_EVENT_VALUE_CHANGED, NULL);在资源受限的嵌入式设备上建议使用lv_snprintf替代printf系列函数可以节省约3KB的Flash空间。