PAYATHON 2026

Flet Python 中的 expand 选项为何无法让三个 Card 水平撑满?

排障赵师傅

要让右侧三个 Card 横向撑满,在承载它们的 Column 上设置:

horizontal_alignment=ft.CrossAxisAlignment.STRETCH

建议同时去掉每个 Card 外面只用于布局的 Container,让 Card 直接成为 Column 的子控件。这样就可以用 Card.expand 分配高度,用 Column.horizontal_alignment 拉伸宽度。

为什么设置了 expand,宽度仍然不变?

expand 的作用方向取决于直接父布局:

直接父布局子控件设置 expand 的作用
Row沿水平方向分配可用宽度
Column沿垂直方向分配可用高度

右侧 Column 中三个 Container 的 expand=True 分配的是高度,所以代码中已经出现了垂直展开的效果。宽度由交叉轴布局控制,具体见 Flet 的展开布局说明。

原代码还存在一层嵌套:

Column
└── Container(expand=True)
    └── Card(expand=1)

Card 的直接父控件是 Container,所以它的 expand=1 不参与外层 Column 的空间分配。expand 由直接父布局处理,不能跨过中间的 Container 生效,见 Control.expand 文档。

Column.horizontal_alignment 默认是 START,子控件会靠起始侧排列。改为 STRETCH 后,子控件会填满交叉轴,也就是 Column 的水平方向。见 Column 文档和 CrossAxisAlignment 文档。

如何调整代码?

保留左侧 IP 选择区域,将右侧结构简化为 Column → Card → Container:

  1. 将右侧 Column 直接放进外层 Row,用 expand=True 分配宽度。
  2. 在右侧 Column 上设置 horizontal_alignment=ft.CrossAxisAlignment.STRETCH。
  3. 给三个 Card 设置相同的 expand 值,继续均分可用高度。

假设已经导入 flet as ft,且 IPBox 已定义,可以用以下代码替换原来的 mainpage 定义:

mainpage = ft.Row(
    controls=[
        ft.Container(
            content=ft.Card(
                content=ft.Container(
                    content=ft.Column(
                        controls=[
                            ft.Text(
                                "Select your IP",
                                weight=ft.FontWeight.BOLD,
                                size=18,
                                text_align=ft.TextAlign.CENTER,
                            ),
                            *IPBox,
                        ],
                        spacing=5,
                        horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                    ),
                    padding=20,
                ),
            ),
            expand=True,
        ),
        ft.Column(
            controls=[
                ft.Card(
                    content=ft.Container(
                        content=ft.Text(f"Card {i}"),
                        padding=20,
                    ),
                    expand=True,
                )
                for i in range(1, 4)
            ],
            spacing=10,
            horizontal_alignment=ft.CrossAxisAlignment.STRETCH,
            expand=True,
        ),
    ],
    expand=True,
)

外层 Row 会根据右侧 Column 的 expand=True 为它分配宽度;右侧 Column 则根据三个 Card 的 expand=True 分配高度,并通过 STRETCH 将卡片横向拉伸。

还需要注意什么?

左右两个直接子控件都设置了 expand=True,会按相同权重分配外层 Row 的可用宽度。如果希望右侧更宽,可以将左侧设为 expand=1,右侧 Column 设为 expand=2。

展开效果取决于父布局提供的空间。这段代码假设 mainpage 能获得页面的可用宽度,并且有有限的高度可供分配。如果外层限制了宽度,内部卡片也只能填满这个范围。要保留高度均分效果,应避免将它放进垂直方向没有有限高度约束的滚动布局中。

如果卡片边缘只剩少量留白,可以检查 Card.margin 和外围 padding。这些间距与右侧大片区域未填满的问题,需要分别检查。

备注:内容仅供参考。