专业编程基础技术教程

网站首页 > 基础教程 正文

Flet 布局控件:ft.DataTable(数据表)

ccvgpt 2025-02-26 11:08:23 基础教程 4 ℃

数据表(DataTable)是一种Material Design风格的数据表格。

一、基本用法

Flet 布局控件:ft.DataTable(数据表)

举例演示:创建了一个包含三列的DataTable(数据表),并设置了中文的列标题。添加了排序模拟,用print语句输出,没有真正实现排序逻辑。

import flet as ft

def main(page: ft.Page):
    def sort_1(column_index, ascending):
        print(f"正在对第 {column_index + 1} 列进行模拟排序,{'升序' if ascending else '降序'}")

    # 创建数据表,设置列标题为中文
    data_table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("姓名"), on_sort=lambda e: sort_1(e.column_index, e.ascending)),
            ft.DataColumn(ft.Text("年龄"), numeric=True),
            ft.DataColumn(ft.Text("城市")),
        ],
        rows=[
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text("lihua李华")),
                    ft.DataCell(ft.Text("25")),
                    ft.DataCell(ft.Text("北京")),
                ]
            ),
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text("zhangwei张伟")),
                    ft.DataCell(ft.Text("30")),
                    ft.DataCell(ft.Text("上海")),
                ]
            ),
        ],
        sort_column_index=0,
        sort_ascending=True,
        show_bottom_border=True,
    )

    page.add(data_table)

ft.app(target=main)

关键点:

  • ft.DataTable 创建了一个数据表控件,它具有 columns 和 rows 属性,分别定义了表格的列和行。
  • 每个 ft.DataColumn 对应于一列,可以指定列名、是否为数字列(numeric),以及点击列头时触发的排序事件处理函数(on_sort)。
  • show_bottom_border=True 使得表格底部有一条边框线,提高视觉效果。

二、高级用法

(一)带排序功能

示例代码及解读如下:

import flet as ft

def main(page: ft.Page):
    # 初始数据
    data = [
        {"name": "李华", "age": "25", "city": "北京"},
        {"name": "张伟", "age": "30", "city": "上海"},
        {"name": "王芳", "age": "22", "city": "广州"},
    ]
    
    def sort_changed(e):
        # 定义排序状态的非局部变量
        nonlocal sort_column_index, sort_ascending
        
        # 检查是否点击了相同的列
        if e.column_index == sort_column_index:
            # 如果是同一列,则切换排序方向
            sort_ascending = not sort_ascending
        else:
            # 如果是不同的列,则设置为默认升序
            sort_column_index = e.column_index
            sort_ascending = True
        
        # 打印当前排序状态
        print(f"正在对第 {e.column_index + 1} 列进行排序,{'升序' if sort_ascending else '降序'}")
        
        # 根据当前排序状态对数据进行排序
        if sort_column_index == 0:  # 姓名列
            data.sort(key=lambda x: x["name"], reverse=not sort_ascending)
        elif sort_column_index == 1:  # 年龄列
            data.sort(key=lambda x: int(x["age"]), reverse=not sort_ascending)
        elif sort_column_index == 2:  # 城市列
            data.sort(key=lambda x: x["city"], reverse=not sort_ascending)
        
        # 更新表格行
        update_table()
    
    def update_table():
        # 更新行属性
        table.rows = [
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text(row["name"])),
                    ft.DataCell(ft.Text(row["age"])),
                    ft.DataCell(ft.Text(row["city"])),
                ]
            )
            for row in data
        ]
        # 重置排序信息
        table.sort_column_index = sort_column_index
        table.sort_ascending = sort_ascending
        # 更新页面以反映更改
        page.update()

    # 初始化排序状态
    sort_column_index = None
    sort_ascending = True
    
    # 创建包含中文列标题的数据表
    table = ft.DataTable(
        columns=[
            ft.DataColumn(ft.Text("姓名"), on_sort=sort_changed),
            ft.DataColumn(ft.Text("年龄"), numeric=True, on_sort=sort_changed),
            ft.DataColumn(ft.Text("城市"), on_sort=sort_changed),
        ],
        rows=[
            ft.DataRow(
                cells=[
                    ft.DataCell(ft.Text(row["name"])),
                    ft.DataCell(ft.Text(row["age"])),
                    ft.DataCell(ft.Text(row["city"])),
                ]
            )
            for row in data
        ],
        show_bottom_border=True,
    )

    page.add(table)

ft.app(target=main)

关键点:

  • 定义排序状态变量。sort_column_index = None 用于跟踪当前排序的列索引, sort_ascending = True 用于指示排序方向,默认为升序
  • 实现排序变化事件处理函数sort_changed():
  1. nonlocal 关键字用于声明 sort_column_index 和 sort_ascending 不是局部变量,而是外层作用域(这里是 main 函数)中的变量。
  2. e.column_index 提供了用户点击的列索引。
  3. 如果点击的是同一列,则切换排序方向;如果是不同列,则设置为默认升序。
  4. 根据当前的排序状态,通过 lambda 表达式作为 key 参数传递给 list.sort() 方法来对 data 列表进行排序。对于年龄列,需要将字符串转换为整数以正确排序。
  5. 最后调用 update_table 函数更新表格显示。
  • 更新表格行update_table():
  1. update_table 函数负责更新表格的行内容,它遍历 data 列表,并为每一行创建 DataRow 对象,每个 DataRow 包含多个 DataCell 对象,分别对应于表格中的单元格。
  2. 设置 table.sort_column_index 和 table.sort_ascending 来反映当前的排序状态。
  3. 调用 page.update() 来刷新页面,确保更改后的表格立即显示出来。

(二)带样式的数据表格

示例代码如下:

import flet as ft

def example():

    return ft.DataTable(
        width=600,
        bgcolor="yellow",
        border=ft.border.all(2, "red"),
        border_radius=10,
        vertical_lines=ft.border.BorderSide(3, "blue"),
        horizontal_lines=ft.border.BorderSide(1, "green"),
        sort_column_index=0,
        sort_ascending=True,
        heading_row_color=ft.Colors.BLACK12,
        heading_row_height=100,
        data_row_color={"hovered": "0x30FF0000"},
        show_checkbox_column=True,
        divider_thickness=0,
        column_spacing=200,
        columns=[
            ft.DataColumn(
                ft.Text("第一列"),
                on_sort=lambda e: print(f"{e.column_index}, {e.ascending}"),
            ),
            ft.DataColumn(
                ft.Text("第二列"),
                tooltip="这是第二列",
                numeric=True,
                on_sort=lambda e: print(f"{e.column_index}, {e.ascending}"),
            ),
        ],
        rows=[
            ft.DataRow(
                [ft.DataCell(ft.Text("A")), ft.DataCell(ft.Text("1"))],
                selected=True,
                on_select_changed=lambda e: print(f"选择的行已更改: {e.data}"),
            ),
            ft.DataRow([ft.DataCell(ft.Text("B")), ft.DataCell(ft.Text("2"))]),
        ],
    )

def main(page:ft.Page):
    page.title = "Flet 布局控件:ft.DataTable(数据表)"
    page.window_width = 600
    page.window_height = 400
    page.window_center()
    page.add(example())
ft.app(target=main)

三、DataTable属性

bgcolor

表格的背景颜色。

border

表格周围的边框。该值是 Border 类的实例。Border 类有以下属性描述矩形的 4 条边:

  • bottom
  • left
  • right
  • top

border_radius

边框的圆角。边框半径是 BorderRadius 类的实例。


border_radius.BorderRadius 类具有描述四个角值的以下属性:

  • top_left (左上)
  • top_right (右上)
  • bottom_left (左下)
  • bottom_right (右下)

可以使用构造函数分别设置所有角的值,也可以使用辅助方法:

  • border_radius.all(value) (所有角相同)
  • border_radius.horizontal(left: float = 0, right: float = 0) (水平方向)
  • border_radius.vertical(top: float = 0, bottom: float = 0) (垂直方向)
  • border_radius.only(top_left, top_right, bottom_left, bottom_right) (指定角)

checkbox_horizontal_margin

复选框周围的水平边距,如果显示的话。

clip_behavior

根据此选项,内容将被裁剪(或不裁剪)。值的类型为 ClipBehavior ,如果 border_radius!=None ,则默认为 ClipBehavior.ANTI_ALIAS ;否则为 ClipBehavior.HARD_EDGE 。

ClipBehavior 枚举具有以下值:

  • NONE(无裁剪)
  • ANTI_ALIAS(反锯齿)
  • ANTI_ALIAS_WITH_SAVE_LAYER(带保存图层的反锯齿)
  • HARD_EDGE(硬边缘)

column_spacing

每列内容之间的水平间距。

columns

描述表格列的 DataColumn 控件列表。

data_row_color

数据行的背景颜色。

有效的背景颜色可以取决于ControlState状态, 即如果行被选中、按下、悬停、聚焦、禁用或启用。颜色作为覆盖层绘制到行上。为确保行的 InkWell 可见(当按下、悬停和聚焦时),建议使用半透明的背景颜色。

data_row_min_height

每行的最小高度(不包括包含列标题的行)。 默认值为“48.0”,且必须小于或等于“data_row_max_height”。

data_row_max_height

每行的最大高度(不包括包含列标题的行)。将其设置为 float("inf") 以使每行的高度根据其内容自动调整。

默认值为 48.0 ,并且必须大于或等于 data_row_min_height 。

data_text_style

数据行的文本样式。是 TextStyle 类的实例。

divider_thickness

出现在 TableRow 之间的分隔线的宽度。必须大于或等于零。该值默认为 1.0。

gradient

表格的背景渐变色。值类型为 Gradient

heading_row_alignment

标题行对齐方式。该值的类型为MainAxisAlignment。

heading_row_color

标题行的背景颜色。

有效的背景颜色可以根据 ControlState 状态(即行是否按下、悬停、聚焦时进行排序)进行调整。颜色作为行的覆盖层进行绘制。为了确保行的墨水效果可见(在按下、悬停和聚焦时),建议使用半透明的颜色。

heading_row_height

标题行的高度。

heading_text_style

标题行的文本样式。是 TextStyle 类的实例。

horizontal_lines

设置行之间水平线的颜色和宽度。是 BorderSide 类的实例。

horizontal_margin

表格边缘与每行第一个和最后一个单元格内容之间的水平边距。显示复选框时,它也是复选框与第一个数据列内容之间的边距。

rows

定义表格行的 DataRow 控件列表。

show_bottom_border

是否显示表格底部的边框。默认情况下,不显示底部边框以允许通过装饰定义表格周围的边框。

show_checkbox_column

是否应显示可选行的复选框。

如果为 True,则在每个可选行的开头放置一个 Checkbox。然而,如果任何行的 DataRow.on_select_changed 未设置,即使该值为 True,也不会放置复选框。

如果为 False,则所有行都不会显示 Checkbox。

sort_ascending

指定的 sort_column_index 列是否按升序排序。

如果为 True,则顺序为升序(意味着当前排序列的最小值的行在表格的最前面)。

如果为 False,则顺序为降序(意味着当前排序列的最小值的行在表格的最后面)。

sort_column_index

当前主要排序键的列。如果指定,则表示数据按所指示的列进行排序。该数字必须对应于 columns 中相关列的索引。设置此值会导致相关列显示排序指示器。当此值为 None 时,表示表格的排序顺序不对应于任何列。

vertical_lines

设置列之间垂直线的颜色和宽度。是 BorderSide 类的实例。

四、DataTable 事件

on_select_all

当用户使用标题行中的复选框选择或取消选择每行时调用。

如果为 None,则适当调用表格中每行的 DataRow.on_select_changed 回调。

要控制特定行是否可选,请参见 DataRow.on_select_changed。此回调仅在任何行可选时相关。

五、DataColumn —— DataTable 的列配置

每个要显示在表格中的列都必须提供一个列配置。

label

列标题。通常是一个 Text 控件。它也可以是一个 Icon(通常使用大小18),或一个带有图标和一些文本的 Row。

numeric

此列是否表示数字数据。包含数字数据的列的单元格内容是右对齐的。

tooltip

列标题的工具提示。这是列标题的更长描述,用于标题可能已缩写以保持列宽合理的情况。

六、DataColumn 事件

on_sort

当用户请求使用此列排序表格时调用。如果未设置,则不考虑该列可排序性。

七、DataRow —— DataTable 的行配置和单元格数据

每个要显示在表格中的行都必须提供一个行配置。该行的表格数据在 DataRow 对象的 cells 属性中提供。

cells

该行的数据 - DataCell 控件列表。

必须有与表格中的列数完全相同的单元格。

color

该行的颜色。默认情况下,颜色是透明的,除非被选中。选中的行有灰色半透明颜色。

有效颜色可以根据 ControlState 状态(如果行被选中、按下、悬停、聚焦、禁用或启用)进行调整。颜色作为行的覆盖层进行绘制。为了确保行的墨水效果可见(在按下、悬停和聚焦时),建议使用半透明颜色。

selected

行是否被选中。

如果 on_select_changed 对于表格中的任何行不是null,则在每行的开头显示一个复选框。如果行被选中 (True),则复选框将被选中,行将被高亮显示。

否则,复选框(如果存在)将不会被选中。

八、DataRow 事件

on_long_press

如果行被长按,则调用。

如果行中的 DataCell 定义了其 DataCell.on_tap、DataCell.on_double_tap、DataCell.on_long_press、DataCell.on_tap_cancel 或 DataCell.on_tap_down 回调,则该回调行为会覆盖该特定单元格的行手势行为。

on_select_changed

当用户选择或取消选择可选行时调用。

如果这不是null,则该行是可选的。行的当前选择状态由 selected 给出。

如果任何行是可选的,则表格的标题行将有一个复选框,该复选框可以选择所有可选行(并且如果所有行都被选中则会选中),每行将有一个复选框以切换该行。

如果行的 on_select_changed 回调为null,则在确定“全选”复选框的状态时会忽略该行,其复选框将被禁用。

如果行中的 DataCell 定义了其 DataCell.on_tap 回调,则该回调行为会覆盖该特定单元格的行手势行为。

九、DataCell —— DataTable 单元格的数据

每个 DataRow 必须提供一个 DataCell 对象列表。

content

行的数据。通常是一个 Text 控件或一个 Dropdown 控件。

如果单元格没有数据,则应提供一个带有占位符文本的 Text 控件,并将 placeholder 设置为 True。

此控件只能有一个子控件。要布置多个子控件,请将此控件的子控件设为具有 controls 属性的 Row、Column 或 Stack 等控件,然后为该控件提供子控件。

placeholder

子控件是否实际上是占位符。如果为 True,则单元格的默认文本样式会更改为适用于占位符文本。

show_edit_icon

是否在单元格末尾显示编辑图标。

这不会使单元格实际上可编辑;调用方必须实现所需的编辑行为(从 on_tap 回调启动)。

如果设置了此选项,还应设置 on_tap,否则点击图标将无效。

十、DataCell 事件

on_double_tap

当双击单元格时调用。如果指定,点击单元格将调用此回调,否则(点击单元格将尝试选择行(如果提供了 DataRow.on_select_changed )。

on_long_press

如果长按单元格,则调用。

如果指定,点击单元格将调用此回调,否则(点击单元格将尝试选择行(如果提供了 DataRow.on_select_changed )。

on_tap

如果点击单元格,则调用。

如果指定,点击单元格将调用此回调,否则(点击单元格将尝试选择行(如果提供了 DataRow.on_select_changed )。

on_tap_cancel

如果用户取消了在单元格上开始的点击,则调用。

如果指定,点击单元格将调用此回调,否则(点击单元格将尝试选择行(如果提供了 DataRow.on_select_changed )。

on_tap_down

如果点击单元格,则调用。

如果指定,点击单元格将调用此回调,否则(点击单元格将尝试选择行(如果提供了 DataRow.on_select_changed )。

(汇报完毕,感谢收看!)

Tags:

最近发表
标签列表