跳到主要内容

2 篇博文 含有标签「how-to」

查看所有标签

控件引用

· 阅读需 3 分钟
Feodor Fitsner
Flet创始人兼开发者

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()调用中使用它们的引用(变量)。

当添加了更多的控件和事件处理程序时,将所有控件定义放在一个地方变得具有挑战性,它们会分散在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.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的控件,但这只是个人偏好的问题 :)

试试Flet,并告诉我们你的想法!

在Flet应用中使用自定义字体

· 阅读需 3 分钟
Feodor Fitsner
Flet创始人兼开发者

现在您可以在Flet应用中使用自己的字体了!

支持以下字体格式:

  • .ttc
  • .ttf
  • .otf

使用page.fonts属性导入字体。

page.fonts属性设置为一个字典,其中键是字体系列名称,用于引用该字体,值是要导入的字体文件的URL:

def main(page: ft.Page):
page.fonts = {
"Kanit": "https://raw.githubusercontent.com/google/fonts/master/ofl/kanit/Kanit-Bold.ttf",
"Aleo Bold Italic": "https://raw.githubusercontent.com/google/fonts/master/ofl/aleo/Aleo-BoldItalic.ttf"
}
page.update()

# ...

可以通过提供绝对URL从外部资源导入字体,或者通过提供相对URL和assets_dir从应用程序资源导入字体。

flet.app()调用中指定assets_dir以设置应用程序可用的资源位置。assets_dir可以是相对于main.py目录的路径或绝对路径。例如,考虑以下程序结构:

/assets
/fonts
/OpenSans-Regular.ttf
main.py

代码示例

以下程序从GitHub加载"Kanit"字体,并从资源中加载"Open Sans"字体。"Kanit"被设置为默认应用程序字体,"Open Sans"用于特定的Text控件:

import flet as ft

def main(page: ft.Page):
page.title = "Custom fonts"

page.fonts = {
"Kanit": "https://raw.githubusercontent.com/google/fonts/master/ofl/kanit/Kanit-Bold.ttf",
"Open Sans": "fonts/OpenSans-Regular.ttf",
}

page.theme = Theme(font_family="Kanit")

page.add(
ft.Text("This is rendered with Kanit font"),
ft.Text("This is Open Sans font example", font_family="Open Sans"),
)

ft.app(target=main, assets_dir="assets")

静态字体与可变字体

目前只支持静态字体,即仅包含一个具体宽度/粗细/样式组合的字体,例如"Open Sans Regular"或"Roboto Bold Italic"。

可变字体的支持仍在开发中

但是,如果您需要在应用程序中使用可变字体,可以使用fonttools在特定权重下创建静态的"实例",然后使用这些实例:

fonttools varLib.mutator ./YourVariableFont-VF.ttf wght=140 wdth=85

使用Wakamai Fondue在线工具来探索可用的字体特性(例如wght的可能选项)。

试用一下Flet,并告诉我们您的想法