Appearance
计算器教程
在本教程中,你将逐步学习如何使用 Flet 框架在 Python 中创建一个计算器应用,并将其发布为桌面、移动或网页应用。虽然该应用非常简单,但它却是一个多平台应用,具有类似于 iPhone 计算器应用的 UI 界面:

你可以在这里找到在线 Demo。
在本教程中,我们将涵盖创建 Flet 应用的所有基本概念:构建页面布局、添加控件、制作可重用的 UI 界面组件、处理事件以及发布选项。
Flet 入门
要使用 Flet 在 Python 中创建多平台应用,你不需要了解 HTML、CSS 或 JavaScript,但确实需要掌握 Python 的基础知识和面向对象编程。
在创建你的第一个 Flet 应用之前,你需要安装并配置开发环境,这需要 Python 3.10 或更高版本以及 flet 包。
安装好 Flet 后,让我们创建一个简单的 Hello World 应用。
创建 hello.py 文件并写入以下内容:
hello.py
python
import flet as ft
def main(page: ft.Page):
page.add(ft.Text(value="Hello, world!"))
ft.run(main)运行该应用,你将看到一个包含问候语的新窗口:

添加页面控件
现在,你已经准备好创建一个计算器应用了。
首先,你需要一个 Text 控件来显示计算结果,以及几个用于显示数字和操作的 Button 按钮。
创建 calc.py 文件并写入以下内容:
提示
你可以在这里在线尝试。
calc.py
python
import flet as ft
def main(page: ft.Page):
page.title = "Calc App"
result = ft.Text(value="0")
page.add(
result,
ft.Button("AC"),
ft.Button("+/-"),
ft.Button("%"),
ft.Button("/"),
ft.Button("7"),
ft.Button("8"),
ft.Button("9"),
ft.Button("*"),
ft.Button("4"),
ft.Button("5"),
ft.Button("6"),
ft.Button("-"),
ft.Button("1"),
ft.Button("2"),
ft.Button("3"),
ft.Button("+"),
ft.Button("0"),
ft.Button("."),
ft.Button("="),
)
if __name__ == "__main__":
ft.run(main)运行该应用,你将看到类似下面的页面:

构建页面布局
现在,让我们把文本和按钮排列到 6 个水平 Row 中。
将 calc.py 的内容替换为以下代码:
提示
你可以在这里在线尝试。
calc.py
python
import flet as ft
def main(page: ft.Page):
page.title = "Calc App"
result = ft.Text(value="0")
page.add(
ft.Row(controls=[result]),
ft.Row(
controls=[
ft.Button("AC"),
ft.Button("+/-"),
ft.Button("%"),
ft.Button("/"),
]
),
ft.Row(
controls=[
ft.Button("7"),
ft.Button("8"),
ft.Button("9"),
ft.Button("*"),
]
),
ft.Row(
controls=[
ft.Button("4"),
ft.Button("5"),
ft.Button("6"),
ft.Button("-"),
]
),
ft.Row(
controls=[
ft.Button("1"),
ft.Button("2"),
ft.Button("3"),
ft.Button("+"),
]
),
ft.Row(
controls=[
ft.Button("0"),
ft.Button("."),
ft.Button("="),
]
),
)
if __name__ == "__main__":
ft.run(main)运行该应用,你将看到类似下面的页面:

使用 Container 进行装饰
为了在计算器周围添加黑色背景和圆角边框,我们将使用 Container 控件。由于 Container 只能装饰一个控件,我们需要将所有 6 行包裹进一个垂直的 Column 中,并将其作为容器的 content:
以下是向页面添加容器的代码:
python
page.add(
ft.Container(
width=350,
bgcolor=ft.Colors.BLACK,
border_radius=ft.BorderRadius.all(20),
padding=20,
content=ft.Column(
controls= [],
)
)
)样式化控件
为了完成程序的 UI 部分,我们需要更新结果文本和按钮的样式,使其看起来与 iPhone 计算器应用类似。
对于结果文本,让我们指定它的颜色和大小属性:
python
result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)对于按钮,如果我们再次查看我们想要实现的 UI,有 3 种类型的按钮:
- 数字按钮(Digit Buttons):它们有深灰色背景和白色文本,所有按钮大小相同,但
0按钮除外,它的宽度是其他按钮的两倍。 - 操作按钮(Action Buttons):它们有橙色背景和白色文本,所有按钮大小相同。
- 辅助操作按钮(Extra Action Buttons):它们有浅灰色背景和黑色文本,所有按钮大小相同。
这些按钮将在程序中多次使用,因此我们将创建自定义的**样式化控件(Styled Controls)**来复用代码。
由于所有这些类型都应该继承自 Button 类,并具有共同的 text 和 expand 属性,因此让我们创建一个父类 CalcButton:
python
@ft.control
class CalcButton(ft.Button):
expand: int = 1现在,让我们为这三种类型的按钮创建子类:
python
@ft.control
class DigitButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.WHITE_24
color: ft.Colors = ft.Colors.WHITE
@ft.control
class ActionButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.ORANGE
color: ft.Colors = ft.Colors.WHITE
@ft.control
class ExtraActionButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100
color: ft.Colors = ft.Colors.BLACK我们现在将在 Container 中使用这些新类来创建多行按钮:
python
content = ft.Column(
controls=[
ft.Row(
controls=[result],
alignment=ft.MainAxisAlignment.END,
),
ft.Row(
controls=[
ExtraActionButton(content="AC"),
ExtraActionButton(content="+/-"),
ExtraActionButton(content="%"),
ActionButton(content="/"),
]
),
ft.Row(
controls=[
DigitButton(content="7"),
DigitButton(content="8"),
DigitButton(content="9"),
ActionButton(content="*"),
]
),
ft.Row(
controls=[
DigitButton(content="4"),
DigitButton(content="5"),
DigitButton(content="6"),
ActionButton(content="-"),
]
),
ft.Row(
controls=[
DigitButton(content="1"),
DigitButton(content="2"),
DigitButton(content="3"),
ActionButton(content="+"),
]
),
ft.Row(
controls=[
DigitButton(content="0", expand=2),
DigitButton(content="."),
ActionButton(content="="),
]
),
]
)完整代码
以下是该阶段的完整代码:
提示
你可以在这里在线尝试。
calc.py
python
from dataclasses import field
import flet as ft
def main(page: ft.Page):
page.title = "Calc App"
result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)
@ft.control
class CalcButton(ft.Button):
expand: int = field(default_factory=lambda: 1)
@ft.control
class DigitButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.WHITE_24
color: ft.Colors = ft.Colors.WHITE
@ft.control
class ActionButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.ORANGE
color: ft.Colors = ft.Colors.WHITE
@ft.control
class ExtraActionButton(CalcButton):
bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100
color: ft.Colors = ft.Colors.BLACK
page.add(
ft.Container(
width=350,
bgcolor=ft.Colors.BLACK,
border_radius=ft.BorderRadius.all(20),
padding=20,
content=ft.Column(
controls=[
ft.Row(controls=[result], alignment=ft.MainAxisAlignment.END),
ft.Row(
controls=[
ExtraActionButton(content="AC"),
ExtraActionButton(content="+/-"),
ExtraActionButton(content="%"),
ActionButton(content="/"),
]
),
ft.Row(
controls=[
DigitButton(content="7"),
DigitButton(content="8"),
DigitButton(content="9"),
ActionButton(content="*"),
]
),
ft.Row(
controls=[
DigitButton(content="4"),
DigitButton(content="5"),
DigitButton(content="6"),
ActionButton(content="-"),
]
),
ft.Row(
controls=[
DigitButton(content="1"),
DigitButton(content="2"),
DigitButton(content="3"),
ActionButton(content="+"),
]
),
ft.Row(
controls=[
DigitButton(content="0", expand=2),
DigitButton(content="."),
ActionButton(content="="),
],
),
]
),
)
)
if __name__ == "__main__":
ft.run(main)这正是我们想要的效果!

可重用的 UI 组件
虽然你可以继续在 main 函数中编写你的应用,但最佳实践是创建一个可重用的 UI 组件(Reusable UI Component)。
想象一下,你正在开发一个应用头部、一个侧边栏菜单,或者是一个将作为更大项目一部分的 UI(例如,在 Flet 中,我们将在一个更大的展示所有 Flet 框架示例的 “Gallery” 应用中使用这个计算器应用)。
即使你现在还没有想到这样的用途,我们仍然建议你在创建所有 Flet 应用时都要考虑到组合性和可重用性。
为了使计算器应用成为一个可重用的组件,我们将把它的状态和展示逻辑封装在一个独立的 CalculatorApp 类中。
你可以从这里复制此步骤的完整代码。
尝试其他做法
尝试在页面中添加两个 CalculatorApp 组件:
python
# 创建应用实例
calc1 = CalculatorApp()
calc2 = CalculatorApp()
# 将应用的根控件添加到页面中
page.add(calc1, calc2)处理事件
现在让我们让计算器开始工作。我们将为所有按钮使用相同的事件处理器,并使用 content 属性来区分点击不同按钮时执行的操作。
我们将在 CalculatorClass 中定义 button_clicked 方法,并将其传递给每个按钮。以下是 on_click 事件处理器,它会在点击 “AC” 按钮时重置 Text 的值:
python
def button_clicked(self, e):
data = e.control.content
print(f"按下了按钮,数据为 = {data}")
if data == "AC":
self.result.value = "0"通过类似的方法,button_clicked 方法将根据每个按钮的 content 属性来处理不同的计算器操作。你可以从这里复制本步骤的完整代码。
运行应用并查看其实际运行效果:

发布你的应用
恭喜!你已经使用 Flet 创建了计算器应用,它看起来棒极了!现在是时候向世界分享你的应用了!
使用 flet build 命令,Flet Python 应用及其所有依赖项可以被打包成一个独立的独立可执行分发包。
按照这些说明将你的计算器应用打包为桌面可执行程序、移动应用安装包或网页应用。
总结
在本教程中,你学习了如何:
- 创建一个简单的 Flet 应用;
- 使用可重用的 UI 组件;
- 使用 Column、Row 和 Container 控件设计 UI 布局;
- 处理事件;
- 将你的 Flet 应用发布到多个平台;