Skip to content

zlgopen/awtk-widget-table-view

Folders and files

NameName
Last commit message
Last commit date

Latest commit

94d24b1 · Feb 10, 2025

History

89 Commits
Jul 18, 2020
Oct 6, 2024
Oct 6, 2024
Feb 10, 2025
Aug 18, 2023
Feb 20, 2021
Feb 10, 2025
Jan 2, 2021
Jul 18, 2020
Jul 29, 2020
Jul 18, 2020
Jun 2, 2023
Jun 28, 2021
Jul 18, 2020
Jul 19, 2020
Jun 7, 2023

Repository files navigation

awtk-widget-table-view

AWTK 的 ListView 是一个非常强大的控件,在列表项目中可以放比如文本、图片、编辑器、进度条、滑块和下拉框等各种控件。

但是 ListView 最大的问题是,每个列表项都必须事先创建好,这就导致 ListView 显示大量数据时,存在下列问题:

  • 加载速度慢。
  • 比较耗内存。

所以 ListView 在 PC 可以用于显示少于 10K 的数据,而在嵌入式平台上,只能用于显示少于 500 条记录的数据。

TableView 控件就是为了解决 ListView 控件的不足,具有如下特点:

  • 列表项无需事先创建。
  • 数据无需全部加载到内存。
  • 轻松支持数千万条数据记录。
  • 表格中可以放文本、图片、编辑器、进度条、滑块和下拉框等各种控件。

目前使用 32 位数据表示虚拟高度,最大记录数限制为 5000 万条记录。

准备

  1. 获取 awtk 并编译
git clone https://github.com/zlgopen/awtk.git
cd awtk; scons; cd -

运行

  1. 生成示例代码的资源
python scripts/update_res.py all

也可以使用 Designer 打开项目,之后点击 “打包” 按钮进行生成; 如果资源发生修改,则需要重新生成资源。

如果 PIL 没有安装,执行上述脚本可能会出现如下错误:

Traceback (most recent call last):
...
ModuleNotFoundError: No module named 'PIL'

请用 pip 安装:

pip install Pillow
  1. 编译
scons

完整编译选项请参考编译选项

  1. 运行
  • 基本示例
./bin/demo
  • csv 文件查看和编辑
./bin/csv_view

如何使用 table_view

使用 xml 创建 table_view

table_view 由 table_header(可选)、table_client 和 scroll_bar 组成。

  • table_view_t 是表格视图的外壳,它的主要功能是协调 table_client_t 和滚动条。

  • table_header_t 是表格的标题,它其实只是一个普通的容器,完全可以用 view 代替,但用 table_header_t 更具可读性。

  • table_client_t 是表格的数据区,它是一个 table_row_t 的容器。

  • table_row_t 表示表格中的一行,它只是个容器,里面可以文本、图片、编辑器、进度条、滑块和下拉框等各种控件。

在 table_client 中,只需要写一个 table_row,这个 table_row 只是作为模版,由 table_client 根据需要创建。

示例:

<table_view x="10" y="10" w="-20" h="-80">
  <table_header x="0"  y="0" w="-12" h="30" name="title" children_layout="default(r=1,c=0,s=5,m=5)">
    <label w="20%" text="Name" />
    <label w="20%" text="Color"/>
    <label w="40%" text="Value" />
    <label w="20%" text="Action" />
  </table_header>

  <table_client name="table_client" x="0"  y="30" w="-12" h="-30" row_height="40">
    <table_row children_layout="default(r=1,c=0,s=5,m=5)">
      <label name="name"  w="20%" h="100%" text="name" />
      <combo_box name="color" readonly="true" w="20%" h="80%" options="red;green;blue"/>
      <slider name="value" w="40%" h="80%" />
      <button name="remove" w="20%" h="80%" text="Remove" />
    </table_row>
  </table_client>
  <scroll_bar_d name="vbar" x="right" y="0" w="12" h="100%" value="0"/>
</table_view>

编写准备数据的回调函数

table_client 不需要预先创建全部的 table_row,而是在需要时调用回调函数,去填充指定行的数据。以当前的行号和 table_row 对象为参数,实现者在回调函数中,加载当前行的数据,然后设置到 row 的子控件中。

/**
 * @method table_client_set_on_load_data
 * 设置 加载数据的回调函数。
 * @param {widget_t*} widget widget 对象。
 * @param {table_client_on_load_data_t} on_load_data 回调函数。
 * @param {void*} ctx 回调函数的上下文。 
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t table_client_set_on_load_data(widget_t* widget, table_client_on_load_data_t on_load_data,
                                    void* ctx);
/* 示例 */
static ret_t on_load_data(void* ctx, uint32_t index, widget_t* row) {
  char name[32];
  tk_snprintf(name, sizeof(name), "name:%u", index);

  widget_set_text_utf8(widget_lookup(row, "name", TRUE), name);
  widget_set_value(widget_lookup(row, "value", TRUE),index%100);
  widget_set_value(widget_lookup(row, "color", TRUE), 0);

  return RET_OK;
}

...
  table_client_set_on_load_data(client, on_load_data, client);
...

在本回调函数中,还可以调整控件的大小,设置控件的 style。

table_client 控件的属性名及作用如下表所示:

属性名 作用
row_height 行高
rows 最大行数
yoffset 偏移量
yslidable 是否允许y方向滑动
yspeed_scale y方向偏移速度比例

table_client 控件其他特殊函数如下所示,以下两个函数所注册的回调函数执行时机分别是 table_row 创建完成后,与 table_row 创建前,用户可以在创建前后对数据进行预处理或者编辑操作:

typedef ret_t (*table_client_on_create_row_t)(void* ctx, uint32_t row_index, widget_t* row);
/**
 * @method table_client_set_on_create_row
 * 设置 创建行时的回调函数,在回调函数中可以注册控件的事件。
 * @param {widget_t*} widget widget对象。
 * @param {table_client_on_create_row_t} on_create_row 回调函数。
 * @param {void*} ctx 回调函数的上下文。 
 *
 * @return {ret_t} 返回RET_OK表示成功,否则表示失败。
 */
ret_t table_client_set_on_create_row(widget_t* widget, table_client_on_create_row_t on_create_row,
                                     void* ctx);

typedef ret_t (*table_client_on_prepare_row_t)(void* ctx, widget_t* client, uint32_t prepare_cnt);
/**
 * @method table_client_set_on_prepare_row
 * 设置 预处理行(创建行)的回调函数,在回调函数中可以创建行控件。
 * @param {widget_t*} widget widget对象。
 * @param {table_client_on_prepare_row_t} on_prepare_row 回调函数。
 * @param {void*} ctx 回调函数的上下文。 
 *
 * @return {ret_t} 返回RET_OK表示成功,否则表示失败。
 */
ret_t table_client_set_on_prepare_row(widget_t* widget,
                                      table_client_on_prepare_row_t on_prepare_row, void* ctx);

table_row 控件的属性名及作用如下表所示:

属性名 作用
index 行的编号

可以通过 tabel_row 的 index 属性来定位当前位置,以便进行保存等操作。

文档