LVGL透明屏幕叠加层问题:设置后无内容显示求助
问题:LVGL v9实现帧缓冲上的透明叠加标签效果
我在嵌入式设备上运行LVGL v9(lv_port_linux的v9.0/master分支)的示例,想要实现在现有帧缓冲图像之上叠加透明背景的标签——仅渲染标签文字,屏幕和标签背景都要透明。
最初尝试给屏幕和标签设置全透明背景:
- 屏幕设置:
lv_obj_set_style_bg_opa(screen, LV_OPA_TRANSP, 0);
- 标签设置:
lv_style_set_bg_opa(&label_style, LV_OPA_TRANSP);
但这样设置后完全看不到任何内容,只有全透明窗口;如果注释掉屏幕的透明设置,会出现绿色背景的屏幕和背景透明的红色标签,达不到叠加在原有帧图像上的效果。
完整示例代码:
#include "lvgl/lvgl.h" #include <unistd.h> #include <pthread.h> #include <time.h> #include <stdio.h> #include <stdlib.h> static const char * getenv_default(const char * name, const char * dflt) { return getenv(name) ?: dflt; } static lv_obj_t * example_label; int main(void) { lv_init(); const char * device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0"); lv_display_t * disp = lv_linux_fbdev_create(); lv_linux_fbdev_set_file(disp, device); lv_obj_t * screen = lv_obj_create(NULL); lv_screen_load(screen); //lv_obj_set_style_bg_opa(screen, LV_OPA_TRANSP, 0); lv_obj_set_style_bg_color(screen, lv_color_make(0, 255, 0), 0); static lv_style_t label_style; lv_style_init(&label_style); lv_style_set_text_color(&label_style, lv_color_hex(0xFF0000)); lv_style_set_bg_opa(&label_style, LV_OPA_TRANSP); lv_style_set_bg_color(&label_style, lv_color_hex(0x0000FF)); lv_style_set_text_font(&label_style, &lv_font_montserrat_32); example_label = lv_label_create(screen); lv_label_set_text(example_label, "Hello World"); lv_obj_add_style(example_label, &label_style, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_align(example_label, LV_ALIGN_BOTTOM_MID, 0, 0); while(1) { lv_timer_handler(); usleep(5000); } return 0; }
已尝试的lv_conf.h配置调整:
#define LV_COLOR_DEPTH 32 #define LV_USE_LINUX_FBDEV 1 #if LV_USE_LINUX_FBDEV #define LV_LINUX_FBDEV_BSD 0 //#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL //#define LV_LINUX_FBDEV_BUFFER_COUNT 1 #define LV_LINUX_FBDEV_BUFFER_COUNT 2 #define LV_LINUX_FBDEV_BUFFER_SIZE 60 #endif
设备本身通过QT帧缓冲可以实现相同的叠加效果,且旧版本LVGL的LV_COLOR_SCREEN_TRANSP选项在v9中已移除。
解决方案
1. 切换渲染模式为DIRECT
LV_DISPLAY_RENDER_MODE_FULL模式会先清空整个帧缓冲再渲染,直接覆盖原有图像。改成DIRECT模式后,LVGL只会渲染有更新的区域,保留帧缓冲中原有的内容:
修改lv_conf.h中的配置:
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT
2. 彻底关闭屏幕背景绘制
仅设置背景透明度还不够,需要明确关闭屏幕的背景绘制逻辑,避免LVGL清空帧缓冲:
替换原代码中屏幕背景相关的设置:
// 移除原有屏幕背景颜色设置,替换为以下代码 lv_obj_set_style_bg_opa(screen, LV_OPA_TRANSP, LV_PART_MAIN); lv_obj_set_style_bg_color(screen, lv_color_hex(0x00000000), LV_PART_MAIN); // 带全透明alpha的颜色值 lv_obj_set_style_bg_draw(screen, false, LV_PART_MAIN); // 完全关闭背景绘制
3. 简化标签样式(可选)
标签的透明设置已经正确,可以去掉不必要的背景颜色设置(因为透明度已设为全透明,颜色不会生效):
static lv_style_t label_style; lv_style_init(&label_style); lv_style_set_text_color(&label_style, lv_color_hex(0xFF0000)); lv_style_set_bg_opa(&label_style, LV_OPA_TRANSP); lv_style_set_text_font(&label_style, &lv_font_montserrat_32);
4. 检查帧缓冲权限
确保运行程序的用户对/dev/fb0有读写权限,否则无法正确访问帧缓冲实现叠加。可以临时执行chmod 666 /dev/fb0测试,或者将用户加入video组(永久解决)。
内容的提问来源于stack exchange,提问作者hypnomaki
相关产品推荐
相关产品推荐

