跳到主要内容

Control Refs

Flet 控件是对象,为了访问它们的属性,我们需要保持对这些对象的引用(变量)。

考虑以下示例:

import flet as ft

def main(page):

first_name = ft.TextField(label="First name", autofocus=True)
last_name = ft.TextField(label="Last name")
greetings = ft.Column()

def btn_click(e):
greetings.controls.append(ft.Text(f"Hello, {first_name.value} {last_name.value}!"))
first_name.value = ""
last_name.value = ""
page.update()
first_name.focus()

page.add(
first_name,
last_name,
ft.ElevatedButton("Say hello!", on_click=btn_click),
greetings,
)

ft.app(target=main)

main() 方法的开头,我们创建了三个控件,它们将在按钮的 on_click 处理程序中使用:两个 TextField 用于输入名字和姓氏,一个 Column 用于容纳问候信息。我们使用它们的引用(变量)来访问它们的属性。

当更多控件和事件处理程序被添加时,变得很难在一个地方保持所有控件的定义,因此它们变得散落在 main() 主体中。在 page.add() 参数中很难想象(不需要在 IDE 中不断跳转到变量定义)最终的表单是什么样子:

    page.add(
first_name,
last_name,
ft.ElevatedButton("Say hello!", on_click=btn_click),
greetings,
)

first_name 是一个 TextField,它是否设置了 autofocus?greetings 是一个 Row 还是一个 Column

Ref

Flet 提供了 Ref 实用程序类,它允许定义一个控件的引用,使用该引用在事件处理程序中,并在构建树时将其设置为实际控件。这个想法来自 React

要定义一个新的类型控件引用:

first_name = ft.Ref[ft.TextField]()

要访问引用的控件(控件取消引用),使用 Ref.current 属性:

# 清空 first name
first_name.current.value = ""

要将控件分配给一个引用,设置 Control.ref 属性为一个引用:

page.add(
ft.TextField(ref=first_name, label="First name", autofocus=True)
)
备注

所有 Flet 控件都有 ref 属性。

我们可以重写我们的程序以使用引用:

import flet as ft


def main(page):

first_name = ft.Ref[ft.TextField]()
last_name = ft.Ref[ft.TextField]()
greetings = ft.Ref[ft.Column]()

def btn_click(e):
greetings.current.controls.append(
ft.Text(f"Hello, {first_name.current.value} {last_name.current.value}!")
)
first_name.current.value = ""
last_name.current.value = ""
page.update()
first_name.current.focus()

page.add(
ft.TextField(ref=first_name, label="First name", autofocus=True),
ft.TextField(ref=last_name, label="Last name"),
ft.ElevatedButton("Say hello!", on_click=btn_click),
ft.Column(ref=greetings),
)

ft.app(target=main)

现在,我们可以在 page.add() 中清楚地看到页面的结构和它所构建的控件。

是的,逻辑变得有点冗长,因为您需要添加 .current. 来访问 ref 的控件,但是这只是个人喜好问题 :)