用户控制
用户控件 ( UserControl) 允许通过组合现有的 Flet 控件来构建隔离的可重用组件。用户控件的行为类似于Control,可以具有方法和属性。
下面是用户控制的最小示例:
class GreeterControl(UserControl):
    def build(self):
        return Text("Hello!")
def main(page):
    page.add(GreeterControl())
flet.app(target=main)
UserControl 必须实现build()为构建控件的 UI 而调用的方法,并且应该返回单个Control实例或一个List控件。UserControl继承自Stack,因此多个孩子将被安排在彼此之上。如果您需要以不同方式排列控件的 UI Row,请使用Column或其他布局控件,例如:
class GreeterControl(UserControl):
    def build(self):
        return Column([
            TextField(label="Your name"),
            ElevatedButton("Login")
        ])
UserControl 与外部布局隔离,即当update()为父控件调用方法时,UserControl 内部的任何更改都不会包含在更新摘要中。UserControl 应调用self.update()以将其更改推送到 Flet 页面,例如:
class Counter(UserControl):
    def add_click(self, e):
        self.counter += 1
        self.text.value = str(self.counter)
        self.update()
    def build(self):
        self.counter = 0
        self.text = Text(str(self.counter))
        return Row([self.text, ElevatedButton("Add", on_click=self.add_click)])
def main(page):
    page.add(Counter(), Counter())
flet.app(target=main)

您可以将事件处理程序(例如def add_click(self, e))和控件引用(例如self.text)声明为类成员,或者build()使用局部变量和内部函数在方法内部实现所有 UserControl 的逻辑。例如,上面的代码可以重写为:
class Counter(UserControl):
    def build(self):
        self.counter = 0
        text = Text(str(self.counter))
        def add_click(e):
            self.counter += 1
            text.value = str(self.counter)
            self.update()
        return Row([text, ElevatedButton("Add", on_click=add_click)])
class Counter(UserControl):
    def build(self):
        self.counter = 0
        text = Text(str(self.counter))
        def add_click(e):
            self.counter += 1
            text.value = str(self.counter)
            self.update()
        return Row([text, ElevatedButton("Add", on_click=add_click)])
注意
counter不能声明为局部变量,因为它在add_click方法内部不可见,因此必须声明为类字段self.counter。
用户控件可以有一个构造函数来传递自定义数据,例如:
class Counter(UserControl):
    def __init__(self, initial_count):
        super().__init__()
        self.counter = initial_count
    def build(self):
        text = Text(str(self.counter))
        def add_click(e):
            self.counter += 1
            text.value = str(self.counter)
            self.update()
        return Row([text, ElevatedButton("Add", on_click=add_click)])
# then use the control
def main(page):
    page.add(
        Counter(100),
        Counter(200))
注意
super().__init__()必须始终在您自己的构造函数中调用。
用户控件提供生命周期“挂钩”方法:
- did_mount()- 在将- UserControl添加到页面并分配瞬态之后调用id。
- will_unmount()- 在从页面中删除- UserControl之前调用。
使用这些方法,我们可以实现一个简单的“倒计时”控件:
class Countdown(UserControl):
    def __init__(self, seconds):
        super().__init__()
        self.seconds = seconds
    def did_mount(self):
        self.running = True
        self.th = threading.Thread(target=self.update_timer, args=(), daemon=True)
        self.th.start()
    def will_unmount(self):
        self.running = False
    def update_timer(self):
        while self.seconds and self.running:
            mins, secs = divmod(self.seconds, 60)
            self.countdown.value = "{:02d}:{:02d}".format(mins, secs)
            self.update()
            time.sleep(1)
            self.seconds -= 1
    def build(self):
        self.countdown = Text()
        return self.countdown
def main(page):
    page.add(Countdown(120), Countdown(60))
flet.app(target=main)

 
                            