快速概览

在这里,您可以了解有关 LVGL 的最重要内容。 您应该首先阅读此内容以获得总体印象,然后阅读详细的 移植概览 部分。

在模拟器中开始

与直接将 LVGL 移植到嵌入式硬件相比,强烈建议您先在模拟器中开始。

LVGL 已移植到许多 IDE,确保您可以找到自己喜欢的 IDE。 前往 模拟器 部分,获取可在您的 PC 上运行的即用型项目。 通过这种方式,您可以暂时节省移植时间,并立即获得一些使用 LVGL 的经验。

将 LVGL 添加到您的项目中

如果您更愿意在自己的项目中尝试 LVGL,请按照以下步骤操作:

  • 下载 或从 GitHub 克隆库:git clone https://github.com/lvgl/lvgl.git

  • lvgl 文件夹复制到您的项目中。

  • lvgl/lv_conf_template.h 复制为 lv_conf.h,放在 lvgl 文件夹旁边,将第一个 #if 0 改为 1 以启用文件内容,并设置 LV_COLOR_DEPTH 定义。

  • 在需要使用 LVGL 相关功能的文件中包含 lvgl/lvgl.h

  • 在定时器或任务中每隔 x 毫秒调用一次 lv_tick_inc(x)x 应在 1 到 10 之间)。这是 LVGL 内部计时所必需的。 或者,配置 LV_TICK_CUSTOM(参见 lv_conf.h),以便 LVGL 可以直接获取当前时间。

  • 调用 lv_init()

  • 创建一个绘图缓冲区:LVGL 将首先在此处渲染图形,然后将渲染的图像发送到显示器。 缓冲区大小可以自由设置,但屏幕大小的 1/10 是一个不错的起点。

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES / 10];                        /*声明一个 1/10 屏幕大小的缓冲区*/
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_SER / 10);  /*初始化显示缓冲区*/
  • 实现并注册一个函数,用于将渲染的图像复制到显示器的某个区域:

static lv_disp_drv_t disp_drv;        /*显示驱动的描述符*/
lv_disp_drv_init(&disp_drv);          /*基本初始化*/
disp_drv.flush_cb = my_disp_flush;    /*设置您的驱动函数*/
disp_drv.draw_buf = &draw_buf;        /*将缓冲区分配给显示器*/
disp_drv.hor_res = MY_DISP_HOR_RES;   /*设置显示器的水平分辨率*/
disp_drv.ver_res = MY_DISP_VER_RES;   /*设置显示器的垂直分辨率*/
lv_disp_drv_register(&disp_drv);      /*最后注册驱动*/

void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
    int32_t x, y;
    /*这是一个非常慢但简单的实现。
     *`set_pixel` 需要由您编写,用于设置屏幕上的像素*/
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            set_pixel(x, y, *color_p);
            color_p++;
        }
    }

    lv_disp_flush_ready(disp);         /* 表示您已完成刷新*/
}
  • 实现并注册一个函数,用于读取输入设备。例如,触摸板:

static lv_indev_drv_t indev_drv;           /*输入设备驱动的描述符*/
lv_indev_drv_init(&indev_drv);             /*基本初始化*/
indev_drv.type = LV_INDEV_TYPE_POINTER;    /*触摸板是类似指针的设备*/
indev_drv.read_cb = my_touchpad_read;      /*设置您的驱动函数*/
lv_indev_drv_register(&indev_drv);         /*最后注册驱动*/

void my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
{
    /*`touchpad_is_pressed` 和 `touchpad_get_xy` 需要由您实现*/
    if(touchpad_is_pressed()) {
      data->state = LV_INDEV_STATE_PRESSED;
      touchpad_get_xy(&data->point.x, &data->point.y);
    } else {
      data->state = LV_INDEV_STATE_RELEASED;
    }
}
  • 在主 while(1) 循环或操作系统任务中每隔几毫秒定期调用 lv_timer_handler()。 它将在需要时重绘屏幕,处理输入设备、动画等。

有关更详细的指南,请访问 移植 部分。

学习基础知识

小部件

按钮、标签、滑块、图表等图形元素被称为对象或小部件。前往 小部件 查看可用小部件的完整列表。

每个对象都有一个父对象作为其创建的基础。例如,如果在按钮上创建一个标签,则按钮是标签的父对象。

子对象会随父对象移动,如果父对象被删除,子对象也会被删除。

子对象只能在其父对象的边界区域内可见。换句话说,超出父对象的部分将被裁剪。

屏幕是“根”父对象。您可以拥有任意数量的屏幕。

调用 lv_scr_act() 获取当前屏幕,使用 lv_scr_load(scr1) 加载屏幕。

您可以使用 lv_<type>_create(parent) 创建一个新对象。它将返回一个 lv_obj_t * 变量,可用作对象的引用以设置其参数。

例如:

lv_obj_t * slider1 = lv_slider_create(lv_scr_act());

要设置一些基本属性,可以使用 lv_obj_set_<parameter_name>(obj, <value>) 函数。例如:

lv_obj_set_x(btn1, 30);
lv_obj_set_y(btn1, 10);
lv_obj_set_size(btn1, 200, 50);

除了基本属性,小部件还可以有特定类型的参数,这些参数通过 lv_<widget_type>_set_<parameter_name>(obj, <value>) 函数设置。例如:

lv_slider_set_value(slider1, 70, LV_ANIM_ON);

要查看完整的 API,请访问小部件的文档或相关的头文件(例如 lvgl/src/widgets/lv_slider.h)。

...其余内容翻译类似...