自定义控件
虽然 Flet 提供了 100 多个内置控件,可以单独使用,但使用 Flet 编程的真正美丽之处在于所有这些控件可以使用 Python 对象oriented 编程概念来创建可重用的 UI 组件。
您可以通过样式化和/或组合现有的 Flet 控件在 Python 中创建自定义控件。
样式控件
您可以创建的最简单的自定义控件是样式控件,例如,具有特定颜色和行为的按钮,该按钮将在应用程序中多次使 用。
要创建样式控件,您需要创建一个继承自 Flet 控件的新类,例如 ElevatedButton
:
class MyButton(ft.ElevatedButton):
def __init__(self, text):
super().__init__()
self.bgcolor = ft.colors.ORANGE_300
self.color = ft.colors.GREEN_800
self.text = text
您的控 件具有构造函数,以便自定义属性和事件,并传递自定义数据。请注意,您必须在自己的构造函数中调用 super().__init__()
,以便访问 Flet 控件的属性和方法,该控件是您继承的。
现在,您可以在应用程序中使用 MyButton 控件:
import flet as ft
def main(page: ft.Page):
page.add(MyButton(text="OK"), MyButton(text="Cancel"))
ft.app(target=main)
在 计算器应用教程 中查看使用样式控件的示例。
处理事件
类似于属性,您可以将事件处理程序作为参数传递到自定义控件类构造函数中:
import flet as ft
class MyButton(ft.ElevatedButton):
def __init__(self, text, on_click):
super().__init__()
self.bgcolor = ft.colors.ORANGE_300
self.color = ft.colors.GREEN_800
self.text = text
self.on_click = on_click
def main(page: ft.Page):
def ok_clicked(e):
print("OK clicked")
def cancel_clicked(e):
print("Cancel clicked")
page.add(
MyButton(text="OK", on_click=ok_clicked),
MyButton(text="Cancel", on_click=cancel_clicked),
)
ft.app(target=main)
组合控件
组合自定义控件继承自容器控件,如 Column
、Row
、Stack
或甚至 View
,以组合多个 Flet 控件。以下示例是一个 Task
控件,可以在 To-Do 应用程序中使用:
import flet as ft
class Task(ft.Row):
def __init__(self, text):
super().__init__()
self.text_view = ft.Text(text)
self.text_edit = ft.TextField(text, visible=False)
self.edit_button = ft.IconButton(icon=ft.icons.EDIT, on_click=self.edit)
self.save_button = ft.IconButton(
visible=False, icon=ft.icons.SAVE, on_click=self.save
)
self.controls = [
ft.Checkbox(),
self.text_view,
self.text_edit,
self.edit_button,
self.save_button,
]
def edit(self, e):
self.edit_button.visible = False
self.save_button.visible = True
self.text_view.visible = False
self.text_edit.visible = True
self.update()
def save(self, e):
self.edit_button.visible = True
self.save_button.visible = False
self.text_view.visible = True
self.text_edit.visible = False
self.text_view.value = self.text_edit.value
self.update()
def main(page: ft.Page):
page.add(
Task(text="Do laundry"),
Task(text="Cook dinner"),
)
ft.app(target=main)
您可以在 社区示例 和 flet-contrib 存储库中找到更多组合自定义控 件的示例。
生命周期方法
自定义控件提供了生命周期“钩子”方法,您可能需要在应用程序中使用这些方法。
build()
build()
方法在控件被创建并分配其 self.page
时被调用。
如果您需要在控件构造函数中执行逻辑,因为它需要访问 self.page
,则可以覆盖 build()
方法。例如,选择适合 self.page.platform
的图标,以便为您的自适应应用程序 adaptive app。
did_mount()
did_mount()
方法在控件被添加到页面并分配临时 uid
后被调用。
如果您需要在控件被添加到页面后执行逻辑,例如 Weather 小部件,该小部件每分钟调用 Open Weather API 来更新自己以获取最新的天气条件,则可以覆盖 did_mount()
方法。
will_unmount()
will_unmount()
方法在控件被从页面中删除之前被调用。
覆盖 will_unmount()
方法以执行清洁代码。
before_update()
before_update()
方法在控件被更新时被调用。
请确保不要在 before_update()
方法中调用 update()
方法。
隔离控件
自定义控件具有 is_isolated
属性,默认为 False
。
如果您将 is_isolated
设置为 True
,您的控件将从外部布局中隔离,即当调用父控件的 update()
方法时,控件本身将被更新,但控件的子控件的任何更改都不会包含在更新摘要中。隔离控件应该调用 self.update()
将其更改推送到 Flet 页面。
作为最佳实践,任何在其类方法中调用 self.update()
的自定义控件都应该被隔离。
在上面的示例中,简单的样式 MyButton
不需要被隔离,但 Task
应该被隔离:
class Task(ft.Row):
def __init__(self, text):
super().__init__()
self.isolated = True