Flet DataColumnSize 详解:用 S/M/L 相对尺寸与 fixed_width 精准控制 DataTable2 列宽

  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址: https://gitcode.com/gh_mirrors/fl/flet
点击查看 免费下载

导读

flet-datatable2 是 Flet 生态中基于 Flutter data_table_2 封装的数据表扩展,在保留内置 DataTable 全部能力的基础上,增加了吸顶表头、固定行/列等增强特性(DataTable2 总览)。本文聚焦其中的列宽控制核心类型 DataColumnSize:它定义了 S(小)、M(中)、L(大)三档相对尺寸,与 DataTable2.lm_ratio、sm_ratio 两个比例参数协同工作,配合 DataColumn2.fixed_width 绝对像素宽度,可以让数据表的列宽布局做到“相对弹性 + 绝对可控”。读完本文,你将掌握三种列宽分配方式的原理、默认比例关系、源码级实现依据,以及可直接复制的实战示例。

一、DataColumnSize 是什么

DataColumnSize 定义在 sdk/python/packages/flet-datatable2/src/flet_datatable2/datacolumn2.py,是一个基于 Python Enum 的枚举类型:

class DataColumnSize(Enum):
    """
    Relative size of a column determines the share of total table
    width allocated to each individual column.

    When determining column widths, ratios between `S`, `M` and `L`
    columns are kept (i.e. Large columns are set to 1.2x width of Medium ones).

    See :attr:`flet_datatable2.DataTable2.sm_ratio`, \
    :attr:`flet_datatable2.DataTable2.lm_ratio`.
    """

    S = "s"
    M = "m"
    L = "l"

它只有三个取值:

枚举值字符串值含义
DataColumnSize.S"s"小尺寸列,占相对较少的宽度
DataColumnSize.M"m"中尺寸列,作为比例基准
DataColumnSize.L"l"大尺寸列,占相对较多的宽度

它的本质是“相对尺寸”,不是像素绝对值。表的总宽度由 DataTable2 决定(例如 expand=True 时铺满可用空间),各列按照自身的相对尺寸瓜分总宽度。列与列之间保持固定比例关系:L 列宽度是 M 列的 1.2 倍,S 列宽度是 M 列的 0.67 倍(默认配置下)。

枚举值的底层传递

从 Flutter 侧实现看,尺寸枚举会以字符串形式跨语言传递。在 sdk/python/packages/flet-datatable2/src/flutter/flet_datatable2/lib/src/datatable2.dart 中,DataTable2 控件读取 sm_ratio、lm_ratio 属性并直接注入底层 Flutter 表格:

columnSpacing: widget.control.getDouble("column_spacing"),
// ...
smRatio: widget.control.getDouble("sm_ratio", 0.67)!,
lmRatio: widget.control.getDouble("lm_ratio", 1.2)!,

而列本身的 fixed_width 也在同文件第 128 行被读取并映射到底层列的 fixedWidth 参数。也就是说,Python 端的枚举与参数最终都经由 Flet 控件协议映射到 Flutter 渲染层,比例分配的实际计算由 data_table_2 库完成。

二、DataColumn2:承载尺寸的两个属性

DataColumn2 继承自 flet.DataColumn,在父类基础上新增了两个与列宽相关的属性(datacolumn2.py):

class DataColumn2(ft.DataColumn):
    fixed_width: Optional[ft.Number] = None
    """
    Defines absolute width of the column in pixels
    (as opposed to relative :attr:`size` used by default).
    """

    size: Optional[DataColumnSize] = DataColumnSize.S
    """
    Column sizes are determined based on available width by distributing
    it to individual columns accounting for their relative sizes.
    """

两个属性需要重点理解:

  • size: DataColumnSize(默认 DataColumnSize.S):声明该列使用“相对尺寸”参与宽度分配。默认值是 S,即如果只给列设置了 label 而不显式指定尺寸,该列会按小尺寸参与分配。
  • fixed_width: Optional[float](默认 None):声明该列使用“绝对像素宽度”,完全绕开相对比例分配。一旦设置,该列宽度固定为指定的像素数,不再受总宽度和比例影响。

两者的关系是互斥的两种模式:默认走 size 相对分配;设置了 fixed_width 则优先使用绝对宽度。从源码注释可以确认,fixed_width 被明确定义为“与默认相对 size 相对立的绝对宽度”。

三、比例由谁控制:DataTable2 的 lm_ratio 与 sm_ratio

相对尺寸的具体比例并不是写死在枚举里的,而是由 DataTable2 的两个属性调节(datatable2.py):

lm_ratio: ft.Number = 1.2
"""
Ratio of Large column width to Medium.
"""

sm_ratio: ft.Number = 0.67
"""
Ratio of Small column width to Medium.
"""
属性默认值含义
lm_ratio1.2L 列宽度 ÷ M 列宽度
sm_ratio0.67S 列宽度 ÷ M 列宽度

默认比例关系为 S : M : L = 0.67 : 1 : 1.2。M 列是计算的基准单位:

  • L 列 = 1.2 × M 列
  • S 列 = 0.67 × M 列

这两项参数会原样传递到 Flutter 侧的 smRatio / lmRatio,由底层 data_table_2 完成最终的宽度分配计算。因此,调整表格整体的宽窄观感时,不需要逐个改列的 size,只需调整这两个比例;而调整某一列的相对权重,则应修改该列的 size 取值。

此外,若表内容总宽度超出可用空间,可配合 DataTable2.min_width(默认 None)设定最小表宽,超过后触发横向滚动,避免列被过度压缩。

四、实战示例:混合使用相对尺寸与固定宽度

仓库在 sdk/python/examples/extensions/datatable2/column_widths/main.py 中提供了一个完整的列宽控制示例,三种列宽策略一次展示:

import flet as ft
import flet_datatable2 as fdt


def main(page: ft.Page):
    def cell_text(value: str) -> ft.Text:
        """A helper to truncate any overflowing cell text with an ellipsis."""
        return ft.Text(value, overflow=ft.TextOverflow.ELLIPSIS, max_lines=1)

    page.add(
        ft.SafeArea(
            expand=True,
            content=fdt.DataTable2(
                expand=True,
                min_width=600,
                columns=[
                    # Absolute pixel width — best for predictable, short fields.
                    fdt.DataColumn2(label="Name", fixed_width=140),
                    # Relative size S — compact, auto-fits the remaining space.
                    fdt.DataColumn2(label="Role", size=fdt.DataColumnSize.S),
                    # Relative size L — takes the lion's share of what's left.
                    fdt.DataColumn2(label="Recent work", size=fdt.DataColumnSize.L),
                ],
                rows=[
                    ft.DataRow(
                        cells=[
                            ft.DataCell(cell_text("Alice Nakamura")),
                            ft.DataCell(cell_text("Engineer")),
                            ft.DataCell(
                                cell_text(
                                    "Led the migration of our checkout service "
                                    "to a set of composable workers, cutting "
                                    "p99 latency in half."
                                )
                            ),
                        ]
                    ),
                    # ...更多数据行...
                ],
            ),
        )
    )


if __name__ == "__main__":
    ft.run(main)

该示例的选型逻辑值得借鉴:

  1. Name 列使用 fixed_width=140:姓名通常是短字段,用绝对像素锁定宽度,保证布局稳定可预测。示例第二行的超长姓名 “Bartholomew Laurent-Fitzgerald” 超过 140px 后会被 ft.TextOverflow.ELLIPSIS 截断为省略号,而不是撑破列宽——这正是固定宽度 + 文本截断的组合价值。
  2. Role 列使用 size=DataColumnSize.S:角色字段内容短,用小尺寸参与比例分配,紧凑占位。
  3. Recent work 列使用 size=DataColumnSize.L:工作描述文本较长,用大尺寸拿到剩余宽度的“大头”,配合 max_lines=1 的省略号处理,兼顾信息展示与整洁。

运行方式:安装依赖后直接执行 python main.py(或通过 flet run 启动)。示例完整代码见 column_widths/main.py。

五、进阶组合:在可排序、可选择的表格中使用 size

相对尺寸不仅用于静态展示,也可以与排序、行选择等功能组合使用。仓库中的 sortable_and_selectable/main.py 展示了这一场景——在 8 列的甜品数据表中,Name 列显式声明为 L 尺寸:

def get_data_columns() -> list[ftd.DataColumn2]:
    return [
        ftd.DataColumn2(
            label=ft.Text("Name"),
            size=ftd.DataColumnSize.L,
            on_sort=sort_column,
            heading_row_alignment=ft.MainAxisAlignment.START,
        ),
        ftd.DataColumn2(
            label=ft.Text("Calories"),
            on_sort=sort_column,
            numeric=True,
            heading_row_alignment=ft.MainAxisAlignment.END,
        ),
        # ...其余数值列未显式设置 size,默认 DataColumnSize.S...
    ]

值得注意的两个细节:

  • 未显式指定 size 的列(如 Calories、Fat、Carbs 等)会走 DataColumn2.size 的默认值 DataColumnSize.S,以紧凑尺寸参与分配。
  • size 是与 DataColumn2 的排序回调 on_sort、numeric、表头对齐 heading_row_alignment 等属性正交的,列宽控制不会影响排序、选择等交互逻辑。

该示例还使用了 DataTable2 的其他布局参数(column_spacing=0、horizontal_margin=12、bottom_margin=10、min_width=600 等),说明列宽分配是在整个表格布局框架内一起生效的。

六、设计建议与适用边界

综合源码与示例,可以总结出以下选型建议:

  • 字段短且固定(ID、姓名、状态码):优先 fixed_width,用绝对像素锁定宽度,配合单元格文本 overflow=TextOverflow.ELLIPSIS 防止内容撑破布局。
  • 字段内容长短不一、希望弹性分配(描述、备注、长文本):用 size=DataColumnSize.L 等相对尺寸,让列自动适应表格总宽度。
  • 需要整体调节松紧:不要逐个改列,而是调整 DataTable2.lm_ratio 与 sm_ratio,改一处即可改变所有相对列的比例关系。
  • 多列宽窄差异大:混合使用 S / L(甚至 M 作为中间档),利用 0.67 : 1 : 1.2 的默认比例形成自然的视觉层级。

需要特别说明的边界:DataColumnSize 只解决“宽度”问题,它不参与行高、固定行列、排序等逻辑;行高由 DataTable2.data_row_height 或 DataRow2.specific_row_height 控制(后者优先级更高),而吸顶表头、固定左列分别由 fixed_top_rows、fixed_left_columns 控制,这些能力与列宽分配互不干扰(相关实现见 datatable2.py 与 datarow2.py)。

七、安装与运行前提

DataColumnSize 属于 flet-datatable2 扩展包,使用前需要单独安装(README):

# 使用 uv
uv add flet-datatable2

# 使用 pip(之后需手动将其加入 requirements.txt 或 pyproject.toml)
pip install flet-datatable2

该扩展基于 Flutter data_table_2 包实现,支持 Windows、macOS、Linux、iOS、Android 与 Web 全平台。使用时按惯例导入即可:import flet_datatable2 as fdt,随后便可通过 fdt.DataColumn2、fdt.DataColumnSize、fdt.DataTable2 等类构建增强型数据表。

  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址: https://gitcode.com/gh_mirrors/fl/flet
点击查看 免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值