Skip to content

自适应拉伸与填充控件 (Expanding Controls) ​


expand 属性 ​

当子控件被放入 Row、Column、View 或 Page 中时,你可以通过“拉伸(expand)”它来填满可用的剩余空间。

当向 Row 中添加子控件时,你可以利用 expand 属性(所有继承自 Control 的 Flet 控件都拥有该属性),使它们自动变宽/长以填满可用的水平空间。

这让你能够自由控制控件在 Row 或 Column 等布局容器中如何利用剩余的空闲空间。

你可以将 expand 设置为以下值之一:

  • 布尔值(boolean):表示该控件是否应该占用所有可用的剩余空间。
  • 整数(integer):用于在多个拉伸控件之间按比例分配空闲空间(当你需要更精确地控制控件大小时非常有用)。
示例 1 ​

在此示例中,TextField 会被拉伸以填满 Row 中所有的剩余空间,而 Button 则保持与其内容相称的默认大小:

提示

你可以在这里在线尝试。

python
import flet as ft


def main(page: ft.Page):
    page.add(
        ft.SafeArea(
            content=ft.Container(
                width=480,
                padding=10,
                border=ft.Border.all(2, ft.Colors.BLUE_GREY_200),
                border_radius=10,
                content=ft.Row(
                    controls=[
                        ft.TextField(hint_text="Enter your name", expand=True),
                        ft.Button("Join chat"),
                    ]
                ),
            ),
        )
    )


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

TextField 在 Row 中拉伸

示例 2 ​

在此示例中,我们创建了一个包含三个 Container 的 Row,它们占用的空间比例分配为 20% / 60% / 20%:

提示

你可以在这里在线尝试。

python
import flet as ft


def main(page: ft.Page):
    page.add(
        ft.SafeArea(
            content=ft.Container(
                width=500,
                padding=10,
                border=ft.Border.all(2, ft.Colors.BLUE_GREY_200),
                border_radius=10,
                content=ft.Row(
                    spacing=8,
                    controls=[
                        ft.Container(
                            expand=1,
                            height=60,
                            bgcolor=ft.Colors.CYAN_300,
                            alignment=ft.Alignment.CENTER,
                            border_radius=8,
                            content=ft.Text("1"),
                        ),
                        ft.Container(
                            expand=3,
                            height=60,
                            bgcolor=ft.Colors.AMBER_300,
                            alignment=ft.Alignment.CENTER,
                            border_radius=8,
                            content=ft.Text("3"),
                        ),
                        ft.Container(
                            expand=1,
                            height=60,
                            bgcolor=ft.Colors.PINK_200,
                            alignment=ft.Alignment.CENTER,
                            border_radius=8,
                            content=ft.Text("1"),
                        ),
                    ],
                ),
            ),
        )
    )


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

在此处,可用的空闲空间被分成了 5 等份(即 1 + 3 + 1)。第一个和第三个容器各占 1 等份(20%),中间的容器占 3 等份(60%)。

Row 比例拉伸

示例 3 ​

此示例演示了如何通过设置 expand=True,让 Row 内部的两个控件均分并填满水平可用空间(即各占一半)。

该布局使用了一个父级 Container 和一个嵌套的 Row,两个内部 Container 均等拉伸,从而实现 50/50 的均分布局。

提示

你可以在这里在线尝试。

python
import flet as ft


def main(page: ft.Page):
    page.add(
        ft.SafeArea(
            content=ft.Container(
                width=500,
                height=180,
                padding=10,
                border=ft.Border.all(2, ft.Colors.BLUE_GREY_200),
                border_radius=10,
                content=ft.Row(
                    spacing=8,
                    controls=[
                        ft.Container(
                            expand=True,
                            bgcolor=ft.Colors.ORANGE_300,
                            border_radius=8,
                            alignment=ft.Alignment.CENTER,
                            content=ft.Text("Card 1"),
                        ),
                        ft.Container(
                            expand=True,
                            bgcolor=ft.Colors.GREEN_200,
                            border_radius=8,
                            alignment=ft.Alignment.CENTER,
                            content=ft.Text("Card 2"),
                        ),
                    ],
                ),
            ),
        )
    )


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

Row 等宽均分拉伸


expand_loose 属性 ​

expand_loose 属性允许控件在父容器的主轴方向(例如在 Row 中为水平方向,在 Column 中为垂直方向)选择性地拉伸并填充可用空间。

与强行令控件占用所有可用空间的 expand 不同,expand_loose 赋予了控件弹性:如果控件内容需要,它可以扩展变大,但并不强制必须填满所有剩余的空余空间。

注意

要使此属性生效:

  1. 它必须在以下布局容器(或其任何子类)内部的子控件上使用:Row、Column、View、Page。
  2. 使用该属性的控件其 expand 属性的值必须设置为一个非空值(例如 True 或一个整数)。
示例 1 ​

在此示例中,放置于 Rows 中的 Containers 控件将 expand_loose 设置为了 True:

提示

你可以在这里在线尝试。

python
from dataclasses import field

import flet as ft


@ft.control
class Message(ft.Container):
    author: str = ""
    body: str = ""
    border: ft.Border = field(default_factory=lambda: ft.Border.all(1, ft.Colors.BLACK))
    border_radius: ft.BorderRadius = field(
        default_factory=lambda: ft.BorderRadius.all(10)
    )
    bgcolor: ft.Colors = ft.Colors.GREEN_200
    padding: ft.PaddingValue = 10
    expand: bool = True
    expand_loose: bool = True

    def init(self):
        self.content = ft.Column(
            controls=[
                ft.Text(self.author, weight=ft.FontWeight.BOLD),
                ft.Text(self.body),
            ],
        )


def main(page: ft.Page):
    chat = ft.ListView(
        padding=10,
        spacing=10,
        controls=[
            ft.Row(
                alignment=ft.MainAxisAlignment.START,
                controls=[
                    Message(
                        author="John",
                        body="Hi, how are you?",
                    ),
                ],
            ),
            ft.Row(
                alignment=ft.MainAxisAlignment.END,
                controls=[
                    Message(
                        author="Jake",
                        body="Hi I am good thanks, how about you?",
                    ),
                ],
            ),
            ft.Row(
                alignment=ft.MainAxisAlignment.START,
                controls=[
                    Message(
                        author="John",
                        body=(
                            "Lorem Ipsum is simply dummy text of the printing and "
                            "typesetting industry. Lorem Ipsum has been the industry's "
                            "standard dummy text ever since the 1500s, when an unknown "
                            "printer took a galley of type and scrambled it to make a "
                            "type specimen book."
                        ),
                    ),
                ],
            ),
            ft.Row(
                alignment=ft.MainAxisAlignment.END,
                controls=[
                    Message(
                        author="Jake",
                        body="Thank you!",
                    ),
                ],
            ),
        ],
    )

    page.add(
        ft.SafeArea(
            content=ft.Container(
                width=300,
                height=500,
                content=chat,
            )
        ),
    )


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

自适应弹性聊天气泡效果


关注我,学习大模型、大数据、Python等热门技术。