LVGL控件:表格 lv_table

一、概述

表格由行、列和单元格构建而成。

单元格只能包含文本,即任何数值数据在显示前都必须转换为文本格式。

单元格不作为独立的对象存在,而是按需绘制,这就保持了较低的内存占用。

二、部件和样式

  • LV_PART_MAIN:表格的背景。
  • LV_PART_ITEMS:单个单元格。

三、相关函数

1、void lv_table_set_cell_value(lv_obj_t *obj, uint16_t row, uint16_t col, const char *txt)

设置特定单元格的文本值。

会在需要的时候自动添加新的行或列到表格中,以确保指定的行和列存在。

        lv_obj_t *table = lv_table_create(lv_scr_act());
        lv_obj_center(table);
        lv_obj_set_size(table, 400, 300);

        lv_table_set_cell_value(table, 0, 0, "Row 1, Col 1");
        lv_table_set_cell_value(table, 0, 1, "Row 1, Col 2");
        lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
        lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
        lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
        lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");

        lv_table_set_col_width(table, 0, 250);
        lv_table_set_col_width(table, 1, 150);

2、void lv_table_set_cell_value_fmt(lv_obj_t *obj, uint16_t row, uint16_t col, const char *fmt, ...)

向表格中的特定单元格设置格式化字符串作为其值。此函数接受可变数量的参数,类似于C语言中的 printf()函数,可使用各种格式化选项来设置单元格的内容。

  • fmt:类似于 printf()的格式化字符串。可以包含占位符,如%d%s等,用于格式化变量。
  • ...:可变参数列表,与fmt字符串中的占位符相对应。例如,如果 fmt"%d %s",则应提供两个参数,第一个是整数,第二个是字符串。

如果指定的行或列不存在,此函数会自动扩展表格以添加新的行或列,确保指定的位置有效。

        lv_obj_t *table = lv_table_create(lv_scr_act());
        lv_obj_center(table);
        lv_obj_set_size(table, 400, 300);

        lv_table_set_cell_value(table, 0, 0, "Row 1, Col 1");
        lv_table_set_cell_value(table, 0, 1, "Row 1, Col 2");
        lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
        lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
        lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
        lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");

        const char *name = "zhang san";
        int age = 30;

        lv_table_set_cell_value_fmt(table, 0, 0, "%s", name);
        lv_table_set_cell_value_fmt(table, 0, 1, "%d", age);

        lv_table_set_col_width(table, 0, 250);
        lv_table_set_col_width(table, 1, 150);

3、void lv_table_add_cell_ctrl(lv_obj_t *obj, uint16_t row, uint16_t col, lv_table_cell_ctrl_t ctrl)

向指定的单元格添加控制标志。可以用它改变单元格的行为或外观。

  • LV_TABLE_CELL_CTRL_MERGE_RIGHT:与右边单元格合并
  • LV_TABLE_CELL_CTRL_TEXT_CROP:可能是单元格内的文本长度超过了单元格的宽度则裁剪文本(没有实验成功)
  • LV_TABLE_CELL_CTRL_CUSTOM_1:自定义标识
  • LV_TABLE_CELL_CTRL_CUSTOM_2
  • LV_TABLE_CELL_CTRL_CUSTOM_3
  • LV_TABLE_CELL_CTRL_CUSTOM_4

合并单元格:

        lv_obj_t *table = lv_table_create(lv_scr_act());
        lv_obj_center(table);
        lv_obj_set_size(table, 400, 300);
        lv_table_add_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);

        lv_table_set_cell_value(table, 0, 0, "hello wolrd");
        lv_table_set_cell_value(table, 1, 0, "Row 2, Col 1");
        lv_table_set_cell_value(table, 1, 1, "Row 2, Col 2");
        lv_table_set_cell_value(table, 2, 0, "Row 3, Col 1");
        lv_table_set_cell_value(table, 2, 1, "Row 3, Col 2");

        lv_table_set_col_width(table, 0, 250);
        lv_table_set_col_width(table, 1, 150);

官方示例有关于 LV_TABLE_CELL_CTRL_CUSTOM_1 用法的例子:

// 定义表中的项数量
#define ITEM_CNT 200

// 当表中的单元格需要绘制时调用的事件处理程序
static void draw_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);

    // 如果当前绘制的是单元格部分...
    if(dsc->part == LV_PART_ITEMS)
    {
        // 检查该单元格是否具有自定义控件LV_TABLE_CELL_CTRL_CUSTOM_1
        bool chk = lv_table_has_cell_ctrl(obj, dsc->id, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);

        lv_draw_rect_dsc_t rect_dsc;
        lv_draw_rect_dsc_init(&rect_dsc);

        // 设置背景颜色:如果是被标记的单元格,则为主题的主要颜色;否则为淡灰色
        rect_dsc.bg_color = chk ? lv_theme_get_color_primary(obj) : lv_palette_lighten(LV_PALETTE_GREY, 2);
        rect_dsc.radius = LV_RADIUS_CIRCLE; // 设置圆角

        // 计算复选框的位置
        lv_area_t sw_area;
        sw_area.x1 = dsc->draw_area->x2 - 50;
        sw_area.x2 = sw_area.x1 + 40;
        sw_area.y1 = dsc->draw_area->y1 + lv_area_get_height(dsc->draw_area) / 2 - 10;
        sw_area.y2 = sw_area.y1 + 20;

        // 绘制复选框的背景
        lv_draw_rect(&sw_area, dsc->clip_area, &rect_dsc);

        // 绘制复选框的勾选标记
        rect_dsc.bg_color = lv_color_white();
        if(chk) { // 如果单元格被标记
            sw_area.x2 -= 2;
            sw_area.x1 = sw_area.x2 - 16;
        } else { // 如果单元格未被标记
            sw_area.x1 += 2;
            sw_area.x2 = sw_area.x1 + 16;
        }
        sw_area.y1 += 2;
        sw_area.y2 -= 2;
        lv_draw_rect(&sw_area, dsc->clip_area, &rect_dsc);
    }
}

// 当表中的单元格值发生改变时调用的事件处理程序
static void change_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    uint16_t col, row; // 获取当前选中的单元格的行和列
    lv_table_get_selected_cell(obj, &row, &col);

    // 检查该单元格是否具有自定义控件LV_TABLE_CELL_CTRL_CUSTOM_1
    bool chk = lv_table_has_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);

    // 根据单元格状态切换LV_TABLE_CELL_CTRL_CUSTOM_1标志
    if(chk)
        lv_table_clear_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
    else
        lv_table_add_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}

/**
 * 使用表创建一个非常轻量级的列表
 */
void lv_example_table_2(void)
{
    // 监测内存使用情况
    lv_mem_monitor_t mon1;
    lv_mem_monitor(&mon1);

    uint32_t t = lv_tick_get(); // 获取当前时间点

    // 创建表对象
    lv_obj_t * table = lv_table_create(lv_scr_act());

    // 设置表的高度,使其可滚动
    lv_obj_set_size(table, LV_SIZE_CONTENT, 200);

    // 设置第一列的宽度
    lv_table_set_col_width(table, 0, 150);

    // 设置行数,避免频繁的内存重新分配
    lv_table_set_row_cnt(table, ITEM_CNT);

    // 设置列数
    lv_table_set_col_cnt(table, 1);

    // 移除单元格按下的样式,因为我们将自定义绘制
    lv_obj_remove_style(table, NULL, LV_PART_ITEMS | LV_STATE_PRESSED);

    // 填充表的数据
    uint32_t i;
    for(i = 0; i < ITEM_CNT; i++)
        lv_table_set_cell_value_fmt(table, i, 0, "Item %d", i + 1);

    // 对齐表对象至屏幕中心
    lv_obj_align(table, LV_ALIGN_CENTER, 0, -20);

    // 添加绘制结束事件处理程序
    lv_obj_add_event_cb(table, draw_event_cb, LV_EVENT_DRAW_PART_END, NULL);

    // 添加值改变事件处理程序
    lv_obj_add_event_cb(table, change_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    // 再次监测内存使用情况
    lv_mem_monitor_t mon2;
    lv_mem_monitor(&mon2);

    // 计算使用的内存
    long unsigned int mem_used = mon1.free_size - mon2.free_size;

    // 计算创建过程所花费的时间
    unsigned int elaps = lv_tick_elaps(t);

    // 创建标签显示创建信息
    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_label_set_text_fmt(label, "%d items were created in %u ms\n"
                                 "using %lu bytes of memory",
                          ITEM_CNT, elaps, mem_used);

    // 对齐标签至屏幕底部居中
    lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -10);
}

      void lv_table_clear_cell_ctrl(lv_obj_t *obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl)

清除特定单元格的控制标志。

      bool lv_table_has_cell_ctrl(lv_obj_t *obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl)

单元格是否包含特定的控制标志。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值