【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
导读
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_ratio | 1.2 | L 列宽度 ÷ M 列宽度 |
sm_ratio | 0.67 | S 列宽度 ÷ 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)
该示例的选型逻辑值得借鉴:
- Name 列使用
fixed_width=140:姓名通常是短字段,用绝对像素锁定宽度,保证布局稳定可预测。示例第二行的超长姓名 “Bartholomew Laurent-Fitzgerald” 超过 140px 后会被ft.TextOverflow.ELLIPSIS截断为省略号,而不是撑破列宽——这正是固定宽度 + 文本截断的组合价值。 - Role 列使用
size=DataColumnSize.S:角色字段内容短,用小尺寸参与比例分配,紧凑占位。 - 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.
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



