用户控制
用户控件 ( 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)