From 58551a45236b5b70b249d5c72d7ab11786f91de6 Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 19 Nov 2025 10:16:34 -0800 Subject: [PATCH 01/11] Refactor calculator buttons and add dataclass example Simplified button instantiation in calc1.py and calc2.py by removing 'text=' keyword. Refactored calc3.py to use 'content' instead of 'text', updated color and alignment usage, and improved class structure. Added calc3_dataclasses.py to demonstrate using Python dataclasses for calculator button components. --- .../examples/tutorials/calculator/calc1.py | 38 ++++----- .../examples/tutorials/calculator/calc2.py | 38 ++++----- .../examples/tutorials/calculator/calc3.py | 60 +++++++------- .../tutorials/calculator/calc3_dataclasses.py | 83 +++++++++++++++++++ 4 files changed, 151 insertions(+), 68 deletions(-) create mode 100644 sdk/python/examples/tutorials/calculator/calc3_dataclasses.py diff --git a/sdk/python/examples/tutorials/calculator/calc1.py b/sdk/python/examples/tutorials/calculator/calc1.py index d0306ca28f..15db7df583 100644 --- a/sdk/python/examples/tutorials/calculator/calc1.py +++ b/sdk/python/examples/tutorials/calculator/calc1.py @@ -7,25 +7,25 @@ def main(page: ft.Page): page.add( result, - ft.Button(text="AC"), - ft.Button(text="+/-"), - ft.Button(text="%"), - ft.Button(text="/"), - ft.Button(text="7"), - ft.Button(text="8"), - ft.Button(text="9"), - ft.Button(text="*"), - ft.Button(text="4"), - ft.Button(text="5"), - ft.Button(text="6"), - ft.Button(text="-"), - ft.Button(text="1"), - ft.Button(text="2"), - ft.Button(text="3"), - ft.Button(text="+"), - ft.Button(text="0"), - ft.Button(text="."), - ft.Button(text="="), + 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("="), ) diff --git a/sdk/python/examples/tutorials/calculator/calc2.py b/sdk/python/examples/tutorials/calculator/calc2.py index 48be7dfa16..f9fd00b8de 100644 --- a/sdk/python/examples/tutorials/calculator/calc2.py +++ b/sdk/python/examples/tutorials/calculator/calc2.py @@ -9,41 +9,41 @@ def main(page: ft.Page): ft.Row(controls=[result]), ft.Row( controls=[ - ft.Button(text="AC"), - ft.Button(text="+/-"), - ft.Button(text="%"), - ft.Button(text="/"), + ft.Button("AC"), + ft.Button("+/-"), + ft.Button("%"), + ft.Button("/"), ] ), ft.Row( controls=[ - ft.Button(text="7"), - ft.Button(text="8"), - ft.Button(text="9"), - ft.Button(text="*"), + ft.Button("7"), + ft.Button("8"), + ft.Button("9"), + ft.Button("*"), ] ), ft.Row( controls=[ - ft.Button(text="4"), - ft.Button(text="5"), - ft.Button(text="6"), - ft.Button(text="-"), + ft.Button("4"), + ft.Button("5"), + ft.Button("6"), + ft.Button("-"), ] ), ft.Row( controls=[ - ft.Button(text="1"), - ft.Button(text="2"), - ft.Button(text="3"), - ft.Button(text="+"), + ft.Button("1"), + ft.Button("2"), + ft.Button("3"), + ft.Button("+"), ] ), ft.Row( controls=[ - ft.Button(text="0"), - ft.Button(text="."), - ft.Button(text="="), + ft.Button("0"), + ft.Button("."), + ft.Button("="), ] ), ) diff --git a/sdk/python/examples/tutorials/calculator/calc3.py b/sdk/python/examples/tutorials/calculator/calc3.py index c00d0ffe7d..209d3ac694 100644 --- a/sdk/python/examples/tutorials/calculator/calc3.py +++ b/sdk/python/examples/tutorials/calculator/calc3.py @@ -6,26 +6,26 @@ def main(page: ft.Page): result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) class CalcButton(ft.Button): - def __init__(self, text, expand=1): + def __init__(self, content, expand=1): super().__init__() - self.text = text + self.content = content self.expand = expand class DigitButton(CalcButton): - def __init__(self, text, expand=1): - CalcButton.__init__(self, text, expand) - self.bgcolor = ft.Colors.WHITE24 + def __init__(self, content, expand=1): + CalcButton.__init__(self, content, expand) + self.bgcolor = ft.Colors.WHITE_24 self.color = ft.Colors.WHITE class ActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) + def __init__(self, content): + CalcButton.__init__(self, content) self.bgcolor = ft.Colors.ORANGE self.color = ft.Colors.WHITE class ExtraActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) + def __init__(self, content): + CalcButton.__init__(self, content) self.bgcolor = ft.Colors.BLUE_GREY_100 self.color = ft.Colors.BLACK @@ -33,48 +33,48 @@ def __init__(self, text): ft.Container( width=350, bgcolor=ft.Colors.BLACK, - border_radius=ft.border_radius.all(20), + border_radius=ft.BorderRadius.all(20), padding=20, content=ft.Column( controls=[ - ft.Row(controls=[result], alignment="end"), + ft.Row(controls=[result], alignment=ft.MainAxisAlignment.END), ft.Row( controls=[ - ExtraActionButton(text="AC"), - ExtraActionButton(text="+/-"), - ExtraActionButton(text="%"), - ActionButton(text="/"), + ExtraActionButton("AC"), + ExtraActionButton("+/-"), + ExtraActionButton("%"), + ActionButton("/"), ] ), ft.Row( controls=[ - DigitButton(text="7"), - DigitButton(text="8"), - DigitButton(text="9"), - ActionButton(text="*"), + DigitButton("7"), + DigitButton("8"), + DigitButton("9"), + ActionButton("*"), ] ), ft.Row( controls=[ - DigitButton(text="4"), - DigitButton(text="5"), - DigitButton(text="6"), - ActionButton(text="-"), + DigitButton("4"), + DigitButton("5"), + DigitButton("6"), + ActionButton("-"), ] ), ft.Row( controls=[ - DigitButton(text="1"), - DigitButton(text="2"), - DigitButton(text="3"), - ActionButton(text="+"), + DigitButton("1"), + DigitButton("2"), + DigitButton("3"), + ActionButton("+"), ] ), ft.Row( controls=[ - DigitButton(text="0", expand=2), - DigitButton(text="."), - ActionButton(text="="), + DigitButton("0", expand=2), + DigitButton("."), + ActionButton("="), ] ), ] diff --git a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py new file mode 100644 index 0000000000..1803592c95 --- /dev/null +++ b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py @@ -0,0 +1,83 @@ +from dataclasses import dataclass + +import flet as ft + + +def main(page: ft.Page): + page.title = "Calc App" + result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + + @dataclass + class CalcButton(ft.Button): + expand: int = 1 + + @dataclass + class DigitButton(CalcButton): + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE + + @dataclass + class ActionButton(CalcButton): + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE + + @dataclass + 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="="), + ], + ), + ] + ), + ) + ) + + +ft.run(main) From 579d41ff62066b1aba14ea09fc4362e1842e30bb Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 19 Nov 2025 10:34:48 -0800 Subject: [PATCH 02/11] Set default expand value in CalcButton dataclass Replaces the default value assignment for 'expand' in CalcButton with an initializer that sets it to 1 if not already set. This ensures the expand property is always initialized properly. --- sdk/python/examples/tutorials/calculator/calc3_dataclasses.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py index 1803592c95..e939a63900 100644 --- a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py +++ b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py @@ -9,7 +9,9 @@ def main(page: ft.Page): @dataclass class CalcButton(ft.Button): - expand: int = 1 + def init(self): + if self.expand is None: + self.expand = 1 @dataclass class DigitButton(CalcButton): From c71daba1659d6fb773b6594c8bfa996f27d2158d Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Thu, 20 Nov 2025 11:46:49 -0800 Subject: [PATCH 03/11] Update calc3_dataclasses.py --- .../tutorials/calculator/calc3_dataclasses.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py index e939a63900..bae1e8de7e 100644 --- a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py +++ b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field import flet as ft @@ -9,9 +9,16 @@ def main(page: ft.Page): @dataclass class CalcButton(ft.Button): - def init(self): - if self.expand is None: - self.expand = 1 + # def init(self): + # if self.expand is None: + # self.expand = 1 + expand: int = field(default=1) + style: ft.ButtonStyle = field( + default_factory=lambda: ft.ButtonStyle( + shape=ft.RoundedRectangleBorder(radius=10) + ) + ) + icon: ft.IconDataOrControl = field(default_factory=lambda: ft.Icons.HEADPHONES) @dataclass class DigitButton(CalcButton): From 0773dc8c9cfec8563543b268e8667f78de7beb4f Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 26 Nov 2025 08:39:55 -0800 Subject: [PATCH 04/11] Refactor calc3.py to use dataclasses and remove calc3_dataclasses.py Replaces manual class definitions in calc3.py with dataclass-based button classes for cleaner and more concise code. Removes the now-redundant calc3_dataclasses.py file, consolidating the dataclass approach into calc3.py. --- .../examples/tutorials/calculator/calc3.py | 69 +++++++------- .../tutorials/calculator/calc3_dataclasses.py | 92 ------------------- 2 files changed, 33 insertions(+), 128 deletions(-) delete mode 100644 sdk/python/examples/tutorials/calculator/calc3_dataclasses.py diff --git a/sdk/python/examples/tutorials/calculator/calc3.py b/sdk/python/examples/tutorials/calculator/calc3.py index 209d3ac694..3637453ed8 100644 --- a/sdk/python/examples/tutorials/calculator/calc3.py +++ b/sdk/python/examples/tutorials/calculator/calc3.py @@ -1,3 +1,5 @@ +from dataclasses import dataclass, field + import flet as ft @@ -5,29 +7,24 @@ def main(page: ft.Page): page.title = "Calc App" result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + @dataclass class CalcButton(ft.Button): - def __init__(self, content, expand=1): - super().__init__() - self.content = content - self.expand = expand + expand: int = field(default_factory=lambda: 1) + @dataclass class DigitButton(CalcButton): - def __init__(self, content, expand=1): - CalcButton.__init__(self, content, expand) - self.bgcolor = ft.Colors.WHITE_24 - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE + @dataclass class ActionButton(CalcButton): - def __init__(self, content): - CalcButton.__init__(self, content) - self.bgcolor = ft.Colors.ORANGE - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE + @dataclass class ExtraActionButton(CalcButton): - def __init__(self, content): - CalcButton.__init__(self, content) - self.bgcolor = ft.Colors.BLUE_GREY_100 - self.color = ft.Colors.BLACK + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK page.add( ft.Container( @@ -40,42 +37,42 @@ def __init__(self, content): ft.Row(controls=[result], alignment=ft.MainAxisAlignment.END), ft.Row( controls=[ - ExtraActionButton("AC"), - ExtraActionButton("+/-"), - ExtraActionButton("%"), - ActionButton("/"), + ExtraActionButton(content="AC"), + ExtraActionButton(content="+/-"), + ExtraActionButton(content="%"), + ActionButton(content="/"), ] ), ft.Row( controls=[ - DigitButton("7"), - DigitButton("8"), - DigitButton("9"), - ActionButton("*"), + DigitButton(content="7"), + DigitButton(content="8"), + DigitButton(content="9"), + ActionButton(content="*"), ] ), ft.Row( controls=[ - DigitButton("4"), - DigitButton("5"), - DigitButton("6"), - ActionButton("-"), + DigitButton(content="4"), + DigitButton(content="5"), + DigitButton(content="6"), + ActionButton(content="-"), ] ), ft.Row( controls=[ - DigitButton("1"), - DigitButton("2"), - DigitButton("3"), - ActionButton("+"), + DigitButton(content="1"), + DigitButton(content="2"), + DigitButton(content="3"), + ActionButton(content="+"), ] ), ft.Row( controls=[ - DigitButton("0", expand=2), - DigitButton("."), - ActionButton("="), - ] + DigitButton(content="0", expand=2), + DigitButton(content="."), + ActionButton(content="="), + ], ), ] ), diff --git a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py deleted file mode 100644 index bae1e8de7e..0000000000 --- a/sdk/python/examples/tutorials/calculator/calc3_dataclasses.py +++ /dev/null @@ -1,92 +0,0 @@ -from dataclasses import dataclass, 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) - - @dataclass - class CalcButton(ft.Button): - # def init(self): - # if self.expand is None: - # self.expand = 1 - expand: int = field(default=1) - style: ft.ButtonStyle = field( - default_factory=lambda: ft.ButtonStyle( - shape=ft.RoundedRectangleBorder(radius=10) - ) - ) - icon: ft.IconDataOrControl = field(default_factory=lambda: ft.Icons.HEADPHONES) - - @dataclass - class DigitButton(CalcButton): - bgcolor: ft.Colors = ft.Colors.WHITE_24 - color: ft.Colors = ft.Colors.WHITE - - @dataclass - class ActionButton(CalcButton): - bgcolor: ft.Colors = ft.Colors.ORANGE - color: ft.Colors = ft.Colors.WHITE - - @dataclass - 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="="), - ], - ), - ] - ), - ) - ) - - -ft.run(main) From 2ec6999042f8962ad65ca3a93a0d24850b84913f Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 26 Nov 2025 10:28:15 -0800 Subject: [PATCH 05/11] Refactor calculator to use dataclasses and add calc5 example Refactored calc4.py to use Python dataclasses for button and app classes, simplifying initialization and property management. Added calc5_dataclasses.py, a new example with a fully functional calculator app using dataclasses, including button click handling and calculation logic. --- .../examples/tutorials/calculator/calc4.py | 82 +++++---- .../tutorials/calculator/calc5_dataclasses.py | 168 ++++++++++++++++++ 2 files changed, 208 insertions(+), 42 deletions(-) create mode 100644 sdk/python/examples/tutorials/calculator/calc5_dataclasses.py diff --git a/sdk/python/examples/tutorials/calculator/calc4.py b/sdk/python/examples/tutorials/calculator/calc4.py index 80a6796f81..b23d13ef4e 100644 --- a/sdk/python/examples/tutorials/calculator/calc4.py +++ b/sdk/python/examples/tutorials/calculator/calc4.py @@ -1,84 +1,82 @@ +from dataclasses import dataclass, field + import flet as ft +@dataclass class CalcButton(ft.Button): - def __init__(self, text, expand=1): - super().__init__() - self.text = text - self.expand = expand + expand: int = field(default_factory=lambda: 1) +@dataclass class DigitButton(CalcButton): - def __init__(self, text, expand=1): - CalcButton.__init__(self, text, expand) - self.bgcolor = ft.Colors.WHITE24 - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE +@dataclass class ActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) - self.bgcolor = ft.Colors.ORANGE - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE +@dataclass class ExtraActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) - self.bgcolor = ft.Colors.BLUE_GREY_100 - self.color = ft.Colors.BLACK + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK +@dataclass class CalculatorApp(ft.Container): - # application's root control (i.e. "view") containing all other controls - def __init__(self): - super().__init__() - - self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + def init(self): self.width = 350 self.bgcolor = ft.Colors.BLACK - self.border_radius = ft.border_radius.all(20) + self.border_radius = ft.BorderRadius.all(20) self.padding = 20 + self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) self.content = ft.Column( controls=[ - ft.Row(controls=[self.result], alignment="end"), + ft.Row( + controls=[self.result], + alignment=ft.MainAxisAlignment.END, + ), ft.Row( controls=[ - ExtraActionButton(text="AC"), - ExtraActionButton(text="+/-"), - ExtraActionButton(text="%"), - ActionButton(text="/"), + ExtraActionButton(content="AC"), + ExtraActionButton(content="+/-"), + ExtraActionButton(content="%"), + ActionButton(content="/"), ] ), ft.Row( controls=[ - DigitButton(text="7"), - DigitButton(text="8"), - DigitButton(text="9"), - ActionButton(text="*"), + DigitButton(content="7"), + DigitButton(content="8"), + DigitButton(content="9"), + ActionButton(content="*"), ] ), ft.Row( controls=[ - DigitButton(text="4"), - DigitButton(text="5"), - DigitButton(text="6"), - ActionButton(text="-"), + DigitButton(content="4"), + DigitButton(content="5"), + DigitButton(content="6"), + ActionButton(content="-"), ] ), ft.Row( controls=[ - DigitButton(text="1"), - DigitButton(text="2"), - DigitButton(text="3"), - ActionButton(text="+"), + DigitButton(content="1"), + DigitButton(content="2"), + DigitButton(content="3"), + ActionButton(content="+"), ] ), ft.Row( controls=[ - DigitButton(text="0", expand=2), - DigitButton(text="."), - ActionButton(text="="), + DigitButton(content="0", expand=2), + DigitButton(content="."), + ActionButton(content="="), ] ), ] diff --git a/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py new file mode 100644 index 0000000000..a2477cd913 --- /dev/null +++ b/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py @@ -0,0 +1,168 @@ +from dataclasses import dataclass, field + +import flet as ft + + +@dataclass +class CalcButton(ft.Button): + expand: int = field(default_factory=lambda: 1) + + +@dataclass +class DigitButton(CalcButton): + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE + + +@dataclass +class ActionButton(CalcButton): + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE + + +@dataclass +class ExtraActionButton(CalcButton): + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK + + +@dataclass +class CalculatorApp(ft.Container): + def init(self): + self.width = 350 + self.bgcolor = ft.Colors.BLACK + self.border_radius = ft.BorderRadius.all(20) + self.padding = 20 + self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + self.content = ft.Column( + controls=[ + ft.Row( + controls=[self.result], + alignment=ft.MainAxisAlignment.END, + ), + ft.Row( + controls=[ + ExtraActionButton(content="AC", on_click=self.button_clicked), + ExtraActionButton(content="+/-", on_click=self.button_clicked), + ExtraActionButton(content="%", on_click=self.button_clicked), + ActionButton(content="/", on_click=self.button_clicked), + ] + ), + 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="="), + ] + ), + ] + ) + + def button_clicked(self, e): + data = e.control.content + print(f"Button clicked with data = {data}") + if self.result.value == "Error" or data == "AC": + self.result.value = "0" + self.reset() + + elif data in ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."): + if self.result.value == "0" or self.new_operand: + self.result.value = data + self.new_operand = False + else: + self.result.value = self.result.value + data + + elif data in ("+", "-", "*", "/"): + self.result.value = self.calculate( + self.operand1, float(self.result.value), self.operator + ) + self.operator = data + if self.result.value == "Error": + self.operand1 = "0" + else: + self.operand1 = float(self.result.value) + self.new_operand = True + + elif data in ("="): + self.result.value = self.calculate( + self.operand1, float(self.result.value), self.operator + ) + self.reset() + + elif data in ("%"): + self.result.value = float(self.result.value) / 100 + self.reset() + + elif data in ("+/-"): + if float(self.result.value) > 0: + self.result.value = "-" + str(self.result.value) + + elif float(self.result.value) < 0: + self.result.value = str( + self.format_number(abs(float(self.result.value))) + ) + + self.update() + + def format_number(self, num): + if num % 1 == 0: + return int(num) + else: + return num + + def calculate(self, operand1, operand2, operator): + if operator == "+": + return self.format_number(operand1 + operand2) + + elif operator == "-": + return self.format_number(operand1 - operand2) + + elif operator == "*": + return self.format_number(operand1 * operand2) + + elif operator == "/": + if operand2 == 0: + return "Error" + else: + return self.format_number(operand1 / operand2) + + def reset(self): + self.operator = "+" + self.operand1 = 0 + self.new_operand = True + + +def main(page: ft.Page): + page.title = "Calc App" + # create application instance + calc = CalculatorApp() + + # add application's root control to the page + page.add(calc) + + +ft.run(main) From beba2109975203cee9dc1bc326f32e750bc3ee9d Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 26 Nov 2025 10:33:28 -0800 Subject: [PATCH 06/11] Refactor calculator buttons to use @ft.control decorator Replaces @dataclass with @ft.control for button classes in calc3.py and calc4.py to align with Flet's control system. Also updates calc5_dataclasses.py to consistently pass the on_click handler to all DigitButton and ActionButton instances, ensuring button click events are handled properly. --- .../examples/tutorials/calculator/calc3.py | 10 +++--- .../examples/tutorials/calculator/calc4.py | 12 +++---- .../tutorials/calculator/calc5_dataclasses.py | 32 ++++++++++--------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/sdk/python/examples/tutorials/calculator/calc3.py b/sdk/python/examples/tutorials/calculator/calc3.py index 3637453ed8..faf90fd3cf 100644 --- a/sdk/python/examples/tutorials/calculator/calc3.py +++ b/sdk/python/examples/tutorials/calculator/calc3.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, field +from dataclasses import field import flet as ft @@ -7,21 +7,21 @@ def main(page: ft.Page): page.title = "Calc App" result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) - @dataclass + @ft.control class CalcButton(ft.Button): expand: int = field(default_factory=lambda: 1) - @dataclass + @ft.control class DigitButton(CalcButton): bgcolor: ft.Colors = ft.Colors.WHITE_24 color: ft.Colors = ft.Colors.WHITE - @dataclass + @ft.control class ActionButton(CalcButton): bgcolor: ft.Colors = ft.Colors.ORANGE color: ft.Colors = ft.Colors.WHITE - @dataclass + @ft.control class ExtraActionButton(CalcButton): bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 color: ft.Colors = ft.Colors.BLACK diff --git a/sdk/python/examples/tutorials/calculator/calc4.py b/sdk/python/examples/tutorials/calculator/calc4.py index b23d13ef4e..5808f29681 100644 --- a/sdk/python/examples/tutorials/calculator/calc4.py +++ b/sdk/python/examples/tutorials/calculator/calc4.py @@ -1,32 +1,32 @@ -from dataclasses import dataclass, field +from dataclasses import field import flet as ft -@dataclass +@ft.control class CalcButton(ft.Button): expand: int = field(default_factory=lambda: 1) -@dataclass +@ft.control class DigitButton(CalcButton): bgcolor: ft.Colors = ft.Colors.WHITE_24 color: ft.Colors = ft.Colors.WHITE -@dataclass +@ft.control class ActionButton(CalcButton): bgcolor: ft.Colors = ft.Colors.ORANGE color: ft.Colors = ft.Colors.WHITE -@dataclass +@ft.control class ExtraActionButton(CalcButton): bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 color: ft.Colors = ft.Colors.BLACK -@dataclass +@ft.control class CalculatorApp(ft.Container): def init(self): self.width = 350 diff --git a/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py index a2477cd913..e8e76fbafb 100644 --- a/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py +++ b/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py @@ -50,33 +50,35 @@ def init(self): ), ft.Row( controls=[ - DigitButton(content="7"), - DigitButton(content="8"), - DigitButton(content="9"), - ActionButton(content="*"), + DigitButton(content="7", on_click=self.button_clicked), + DigitButton(content="8", on_click=self.button_clicked), + DigitButton(content="9", on_click=self.button_clicked), + ActionButton(content="*", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(content="4"), - DigitButton(content="5"), - DigitButton(content="6"), - ActionButton(content="-"), + DigitButton(content="4", on_click=self.button_clicked), + DigitButton(content="5", on_click=self.button_clicked), + DigitButton(content="6", on_click=self.button_clicked), + ActionButton(content="-", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(content="1"), - DigitButton(content="2"), - DigitButton(content="3"), - ActionButton(content="+"), + DigitButton(content="1", on_click=self.button_clicked), + DigitButton(content="2", on_click=self.button_clicked), + DigitButton(content="3", on_click=self.button_clicked), + ActionButton(content="+", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(content="0", expand=2), - DigitButton(content="."), - ActionButton(content="="), + DigitButton( + content="0", expand=2, on_click=self.button_clicked + ), + DigitButton(content=".", on_click=self.button_clicked), + ActionButton(content="=", on_click=self.button_clicked), ] ), ] From 0e20c258ddf4e2b3b34a3912a3b70fa040568330 Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 26 Nov 2025 10:45:06 -0800 Subject: [PATCH 07/11] Refactor calculator to use @ft.control and dataclasses Refactored calc.py and calc5.py to use @ft.control decorator and dataclass-style field definitions for button and app classes, replacing manual __init__ methods. Updated button instantiation to use 'content' and 'on_click' instead of 'text' and 'button_clicked'. Removed the now-redundant calc5_dataclasses.py file. --- .../examples/tutorials/calculator/calc.py | 91 +++++----- .../examples/tutorials/calculator/calc5.py | 91 +++++----- .../tutorials/calculator/calc5_dataclasses.py | 170 ------------------ 3 files changed, 84 insertions(+), 268 deletions(-) delete mode 100644 sdk/python/examples/tutorials/calculator/calc5_dataclasses.py diff --git a/sdk/python/examples/tutorials/calculator/calc.py b/sdk/python/examples/tutorials/calculator/calc.py index 9ebb3ec650..f699fead6a 100644 --- a/sdk/python/examples/tutorials/calculator/calc.py +++ b/sdk/python/examples/tutorials/calculator/calc.py @@ -1,100 +1,93 @@ +from dataclasses import field + import flet as ft +@ft.control class CalcButton(ft.Button): - def __init__(self, text, button_clicked, expand=1): - super().__init__() - self.text = text - self.expand = expand - self.on_click = button_clicked - self.data = text + expand: int = field(default_factory=lambda: 1) +@ft.control class DigitButton(CalcButton): - def __init__(self, text, button_clicked, expand=1): - CalcButton.__init__(self, text, button_clicked, expand) - self.bgcolor = ft.Colors.WHITE24 - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE +@ft.control class ActionButton(CalcButton): - def __init__(self, text, button_clicked): - CalcButton.__init__(self, text, button_clicked) - self.bgcolor = ft.Colors.ORANGE - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE +@ft.control class ExtraActionButton(CalcButton): - def __init__(self, text, button_clicked): - CalcButton.__init__(self, text, button_clicked) - self.bgcolor = ft.Colors.BLUE_GREY_100 - self.color = ft.Colors.BLACK + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK +@ft.control class CalculatorApp(ft.Container): - # application's root control (i.e. "view") containing all other controls - def __init__(self): - super().__init__() + def init(self): self.reset() - - self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) self.width = 350 self.bgcolor = ft.Colors.BLACK - self.border_radius = ft.border_radius.all(20) + self.border_radius = ft.BorderRadius.all(20) self.padding = 20 + self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + self.content = ft.Column( controls=[ - ft.Row(controls=[self.result], alignment="end"), + ft.Row( + controls=[self.result], + alignment=ft.MainAxisAlignment.END, + ), ft.Row( controls=[ - ExtraActionButton( - text="AC", button_clicked=self.button_clicked - ), - ExtraActionButton( - text="+/-", button_clicked=self.button_clicked - ), - ExtraActionButton(text="%", button_clicked=self.button_clicked), - ActionButton(text="/", button_clicked=self.button_clicked), + ExtraActionButton(content="AC", on_click=self.button_clicked), + ExtraActionButton(content="+/-", on_click=self.button_clicked), + ExtraActionButton(content="%", on_click=self.button_clicked), + ActionButton(content="/", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="7", button_clicked=self.button_clicked), - DigitButton(text="8", button_clicked=self.button_clicked), - DigitButton(text="9", button_clicked=self.button_clicked), - ActionButton(text="*", button_clicked=self.button_clicked), + DigitButton(content="7", on_click=self.button_clicked), + DigitButton(content="8", on_click=self.button_clicked), + DigitButton(content="9", on_click=self.button_clicked), + ActionButton(content="*", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="4", button_clicked=self.button_clicked), - DigitButton(text="5", button_clicked=self.button_clicked), - DigitButton(text="6", button_clicked=self.button_clicked), - ActionButton(text="-", button_clicked=self.button_clicked), + DigitButton(content="4", on_click=self.button_clicked), + DigitButton(content="5", on_click=self.button_clicked), + DigitButton(content="6", on_click=self.button_clicked), + ActionButton(content="-", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="1", button_clicked=self.button_clicked), - DigitButton(text="2", button_clicked=self.button_clicked), - DigitButton(text="3", button_clicked=self.button_clicked), - ActionButton(text="+", button_clicked=self.button_clicked), + DigitButton(content="1", on_click=self.button_clicked), + DigitButton(content="2", on_click=self.button_clicked), + DigitButton(content="3", on_click=self.button_clicked), + ActionButton(content="+", on_click=self.button_clicked), ] ), ft.Row( controls=[ DigitButton( - text="0", expand=2, button_clicked=self.button_clicked + content="0", expand=2, on_click=self.button_clicked ), - DigitButton(text=".", button_clicked=self.button_clicked), - ActionButton(text="=", button_clicked=self.button_clicked), + DigitButton(content=".", on_click=self.button_clicked), + ActionButton(content="=", on_click=self.button_clicked), ] ), ] ) def button_clicked(self, e): - data = e.control.data + data = e.control.content print(f"Button clicked with data = {data}") if self.result.value == "Error" or data == "AC": self.result.value = "0" diff --git a/sdk/python/examples/tutorials/calculator/calc5.py b/sdk/python/examples/tutorials/calculator/calc5.py index 9ebb3ec650..f699fead6a 100644 --- a/sdk/python/examples/tutorials/calculator/calc5.py +++ b/sdk/python/examples/tutorials/calculator/calc5.py @@ -1,100 +1,93 @@ +from dataclasses import field + import flet as ft +@ft.control class CalcButton(ft.Button): - def __init__(self, text, button_clicked, expand=1): - super().__init__() - self.text = text - self.expand = expand - self.on_click = button_clicked - self.data = text + expand: int = field(default_factory=lambda: 1) +@ft.control class DigitButton(CalcButton): - def __init__(self, text, button_clicked, expand=1): - CalcButton.__init__(self, text, button_clicked, expand) - self.bgcolor = ft.Colors.WHITE24 - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE +@ft.control class ActionButton(CalcButton): - def __init__(self, text, button_clicked): - CalcButton.__init__(self, text, button_clicked) - self.bgcolor = ft.Colors.ORANGE - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE +@ft.control class ExtraActionButton(CalcButton): - def __init__(self, text, button_clicked): - CalcButton.__init__(self, text, button_clicked) - self.bgcolor = ft.Colors.BLUE_GREY_100 - self.color = ft.Colors.BLACK + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK +@ft.control class CalculatorApp(ft.Container): - # application's root control (i.e. "view") containing all other controls - def __init__(self): - super().__init__() + def init(self): self.reset() - - self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) self.width = 350 self.bgcolor = ft.Colors.BLACK - self.border_radius = ft.border_radius.all(20) + self.border_radius = ft.BorderRadius.all(20) self.padding = 20 + self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) + self.content = ft.Column( controls=[ - ft.Row(controls=[self.result], alignment="end"), + ft.Row( + controls=[self.result], + alignment=ft.MainAxisAlignment.END, + ), ft.Row( controls=[ - ExtraActionButton( - text="AC", button_clicked=self.button_clicked - ), - ExtraActionButton( - text="+/-", button_clicked=self.button_clicked - ), - ExtraActionButton(text="%", button_clicked=self.button_clicked), - ActionButton(text="/", button_clicked=self.button_clicked), + ExtraActionButton(content="AC", on_click=self.button_clicked), + ExtraActionButton(content="+/-", on_click=self.button_clicked), + ExtraActionButton(content="%", on_click=self.button_clicked), + ActionButton(content="/", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="7", button_clicked=self.button_clicked), - DigitButton(text="8", button_clicked=self.button_clicked), - DigitButton(text="9", button_clicked=self.button_clicked), - ActionButton(text="*", button_clicked=self.button_clicked), + DigitButton(content="7", on_click=self.button_clicked), + DigitButton(content="8", on_click=self.button_clicked), + DigitButton(content="9", on_click=self.button_clicked), + ActionButton(content="*", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="4", button_clicked=self.button_clicked), - DigitButton(text="5", button_clicked=self.button_clicked), - DigitButton(text="6", button_clicked=self.button_clicked), - ActionButton(text="-", button_clicked=self.button_clicked), + DigitButton(content="4", on_click=self.button_clicked), + DigitButton(content="5", on_click=self.button_clicked), + DigitButton(content="6", on_click=self.button_clicked), + ActionButton(content="-", on_click=self.button_clicked), ] ), ft.Row( controls=[ - DigitButton(text="1", button_clicked=self.button_clicked), - DigitButton(text="2", button_clicked=self.button_clicked), - DigitButton(text="3", button_clicked=self.button_clicked), - ActionButton(text="+", button_clicked=self.button_clicked), + DigitButton(content="1", on_click=self.button_clicked), + DigitButton(content="2", on_click=self.button_clicked), + DigitButton(content="3", on_click=self.button_clicked), + ActionButton(content="+", on_click=self.button_clicked), ] ), ft.Row( controls=[ DigitButton( - text="0", expand=2, button_clicked=self.button_clicked + content="0", expand=2, on_click=self.button_clicked ), - DigitButton(text=".", button_clicked=self.button_clicked), - ActionButton(text="=", button_clicked=self.button_clicked), + DigitButton(content=".", on_click=self.button_clicked), + ActionButton(content="=", on_click=self.button_clicked), ] ), ] ) def button_clicked(self, e): - data = e.control.data + data = e.control.content print(f"Button clicked with data = {data}") if self.result.value == "Error" or data == "AC": self.result.value = "0" diff --git a/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py b/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py deleted file mode 100644 index e8e76fbafb..0000000000 --- a/sdk/python/examples/tutorials/calculator/calc5_dataclasses.py +++ /dev/null @@ -1,170 +0,0 @@ -from dataclasses import dataclass, field - -import flet as ft - - -@dataclass -class CalcButton(ft.Button): - expand: int = field(default_factory=lambda: 1) - - -@dataclass -class DigitButton(CalcButton): - bgcolor: ft.Colors = ft.Colors.WHITE_24 - color: ft.Colors = ft.Colors.WHITE - - -@dataclass -class ActionButton(CalcButton): - bgcolor: ft.Colors = ft.Colors.ORANGE - color: ft.Colors = ft.Colors.WHITE - - -@dataclass -class ExtraActionButton(CalcButton): - bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 - color: ft.Colors = ft.Colors.BLACK - - -@dataclass -class CalculatorApp(ft.Container): - def init(self): - self.width = 350 - self.bgcolor = ft.Colors.BLACK - self.border_radius = ft.BorderRadius.all(20) - self.padding = 20 - self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) - self.content = ft.Column( - controls=[ - ft.Row( - controls=[self.result], - alignment=ft.MainAxisAlignment.END, - ), - ft.Row( - controls=[ - ExtraActionButton(content="AC", on_click=self.button_clicked), - ExtraActionButton(content="+/-", on_click=self.button_clicked), - ExtraActionButton(content="%", on_click=self.button_clicked), - ActionButton(content="/", on_click=self.button_clicked), - ] - ), - ft.Row( - controls=[ - DigitButton(content="7", on_click=self.button_clicked), - DigitButton(content="8", on_click=self.button_clicked), - DigitButton(content="9", on_click=self.button_clicked), - ActionButton(content="*", on_click=self.button_clicked), - ] - ), - ft.Row( - controls=[ - DigitButton(content="4", on_click=self.button_clicked), - DigitButton(content="5", on_click=self.button_clicked), - DigitButton(content="6", on_click=self.button_clicked), - ActionButton(content="-", on_click=self.button_clicked), - ] - ), - ft.Row( - controls=[ - DigitButton(content="1", on_click=self.button_clicked), - DigitButton(content="2", on_click=self.button_clicked), - DigitButton(content="3", on_click=self.button_clicked), - ActionButton(content="+", on_click=self.button_clicked), - ] - ), - ft.Row( - controls=[ - DigitButton( - content="0", expand=2, on_click=self.button_clicked - ), - DigitButton(content=".", on_click=self.button_clicked), - ActionButton(content="=", on_click=self.button_clicked), - ] - ), - ] - ) - - def button_clicked(self, e): - data = e.control.content - print(f"Button clicked with data = {data}") - if self.result.value == "Error" or data == "AC": - self.result.value = "0" - self.reset() - - elif data in ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."): - if self.result.value == "0" or self.new_operand: - self.result.value = data - self.new_operand = False - else: - self.result.value = self.result.value + data - - elif data in ("+", "-", "*", "/"): - self.result.value = self.calculate( - self.operand1, float(self.result.value), self.operator - ) - self.operator = data - if self.result.value == "Error": - self.operand1 = "0" - else: - self.operand1 = float(self.result.value) - self.new_operand = True - - elif data in ("="): - self.result.value = self.calculate( - self.operand1, float(self.result.value), self.operator - ) - self.reset() - - elif data in ("%"): - self.result.value = float(self.result.value) / 100 - self.reset() - - elif data in ("+/-"): - if float(self.result.value) > 0: - self.result.value = "-" + str(self.result.value) - - elif float(self.result.value) < 0: - self.result.value = str( - self.format_number(abs(float(self.result.value))) - ) - - self.update() - - def format_number(self, num): - if num % 1 == 0: - return int(num) - else: - return num - - def calculate(self, operand1, operand2, operator): - if operator == "+": - return self.format_number(operand1 + operand2) - - elif operator == "-": - return self.format_number(operand1 - operand2) - - elif operator == "*": - return self.format_number(operand1 * operand2) - - elif operator == "/": - if operand2 == 0: - return "Error" - else: - return self.format_number(operand1 / operand2) - - def reset(self): - self.operator = "+" - self.operand1 = 0 - self.new_operand = True - - -def main(page: ft.Page): - page.title = "Calc App" - # create application instance - calc = CalculatorApp() - - # add application's root control to the page - page.add(calc) - - -ft.run(main) From b8bac9bc1a605a25fd2469a91b342176f6996767 Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Wed, 26 Nov 2025 12:02:09 -0800 Subject: [PATCH 08/11] Refactor calculator tutorial and add integration test Refactored the calculator tutorial documentation to use code includes for examples, updated code snippets for clarity, and improved button class definitions. Added an __init__.py to the calculator example directory and introduced an integration test for the basic calculator example. Also updated calc1.py to use a main guard for script execution. --- .../examples/tutorials/calculator/__init__.py | 0 .../examples/tutorials/calculator/calc1.py | 3 +- .../flet/docs/tutorials/calculator.md | 228 ++++++------------ .../tutorials/test_calculator.py | 73 ++++++ 4 files changed, 146 insertions(+), 158 deletions(-) create mode 100644 sdk/python/examples/tutorials/calculator/__init__.py create mode 100644 sdk/python/packages/flet/integration_tests/tutorials/test_calculator.py diff --git a/sdk/python/examples/tutorials/calculator/__init__.py b/sdk/python/examples/tutorials/calculator/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdk/python/examples/tutorials/calculator/calc1.py b/sdk/python/examples/tutorials/calculator/calc1.py index 15db7df583..df8c33d47f 100644 --- a/sdk/python/examples/tutorials/calculator/calc1.py +++ b/sdk/python/examples/tutorials/calculator/calc1.py @@ -29,4 +29,5 @@ def main(page: ft.Page): ) -ft.run(main) +if __name__ == "__main__": + ft.run(main) diff --git a/sdk/python/packages/flet/docs/tutorials/calculator.md b/sdk/python/packages/flet/docs/tutorials/calculator.md index 4cef4fb162..863e510610 100644 --- a/sdk/python/packages/flet/docs/tutorials/calculator.md +++ b/sdk/python/packages/flet/docs/tutorials/calculator.md @@ -1,10 +1,10 @@ --- title: Calculator Tutorial +examples: ../../examples/tutorials/calculator --- In this tutorial you will learn, step-by-step, how to create a Calculator app in -Python using -Flet framework and publish it as a desktop, mobile or web app. +Python using Flet framework and publish it as a desktop, mobile or web app. The app is a simple console program, yet it is a multi-platform application with similar to iPhone calculator app UI: @@ -56,37 +56,8 @@ and a few [`Button`][flet.Button]s with all the numbers and actions on them. Create `calc.py` with the following contents: -```python title="calc.py" -import flet as ft - -def main(page: ft.Page): - page.title = "Calc App" - result = ft.Text(value="0") - - page.add( - result, - ft.Button(text="AC"), - ft.Button(text="+/-"), - ft.Button(text="%"), - ft.Button(text="/"), - ft.Button(text="7"), - ft.Button(text="8"), - ft.Button(text="9"), - ft.Button(text="*"), - ft.Button(text="4"), - ft.Button(text="5"), - ft.Button(text="6"), - ft.Button(text="-"), - ft.Button(text="1"), - ft.Button(text="2"), - ft.Button(text="3"), - ft.Button(text="+"), - ft.Button(text="0"), - ft.Button(text="."), - ft.Button(text="="), - ) - -ft.run(main) +```python +--8<-- "{{ examples }}/calc1.py" ``` Run the app and you should see a page like this: @@ -100,58 +71,8 @@ Now let's arrange the text and buttons in 6 horizontal [`Row`][flet.Row]s. Replace `calc.py` contents with the following: -```python title="calc.py" -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(text="AC"), - ft.Button(text="+/-"), - ft.Button(text="%"), - ft.Button(text="/"), - ] - ), - ft.Row( - controls=[ - ft.Button(text="7"), - ft.Button(text="8"), - ft.Button(text="9"), - ft.Button(text="*"), - ] - ), - ft.Row( - controls=[ - ft.Button(text="4"), - ft.Button(text="5"), - ft.Button(text="6"), - ft.Button(text="-"), - ] - ), - ft.Row( - controls=[ - ft.Button(text="1"), - ft.Button(text="2"), - ft.Button(text="3"), - ft.Button(text="+"), - ] - ), - ft.Row( - controls=[ - ft.Button(text="0"), - ft.Button(text="."), - ft.Button(text="="), - ] - ), - ) - -ft.run(main) +```python +--8<-- "{{ examples }}/calc2.py" ``` Run the app and you should see a page like this: @@ -175,7 +96,7 @@ Here is the code for adding the container to the page: ft.Container( width=350, bgcolor=ft.Colors.BLACK, - border_radius=ft.border_radius.all(20), + border_radius=ft.BorderRadius.all(20), padding=20, content=ft.Column( controls= [], # (1)! @@ -196,91 +117,95 @@ result = ft.Text(value="0", color=ft.Colors.WHITE, size=20) ``` For the buttons, if we look again at the UI we are aiming to achieve, there are 3 types of buttons: + 1. **Digit Buttons**. They have dark grey background color and white text, size is the same for all. + 2. **Action Buttons**. They have orange background color and white text, size is the same for all except `0` button which is twice as large. + 3. **Extra action buttons**. They have light grey background color and dark text, size is the same for all. The buttons will be used multiple time in the program, so we will be creating custom [Styled Controls](../cookbook/custom-controls.md#styled-controls) to reuse the code. Since all those types should inherit from `Button` class and have common `text` and `expand` properties, let's create a parent `CalcButton` class: + ```python +@ft.control class CalcButton(ft.Button): - def __init__(self, text, expand=1): - super().__init__() - self.text = text - self.expand = expand + expand: int = 1 ``` Now let's create child classes for all three types of buttons: ```python +@ft.control class DigitButton(CalcButton): - def __init__(self, text, expand=1): - CalcButton.__init__(self, text, expand) - self.bgcolor = ft.Colors.WHITE_24 - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.WHITE_24 + color: ft.Colors = ft.Colors.WHITE + +@ft.control class ActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) - self.bgcolor = ft.Colors.ORANGE - self.color = ft.Colors.WHITE + bgcolor: ft.Colors = ft.Colors.ORANGE + color: ft.Colors = ft.Colors.WHITE + +@ft.control class ExtraActionButton(CalcButton): - def __init__(self, text): - CalcButton.__init__(self, text) - self.bgcolor = ft.Colors.BLUE_GREY_100 - self.color = ft.Colors.BLACK + bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100 + color: ft.Colors = ft.Colors.BLACK ``` We will be using these new classes now to create rows of buttons in the Container: ```python -content=ft.Column( - controls=[ - ft.Row(controls=[result], alignment="end"), - ft.Row( - controls=[ - ExtraActionButton(text="AC"), - ExtraActionButton(text="+/-"), - ExtraActionButton(text="%"), - ActionButton(text="/"), - ] - ), - ft.Row( +content = ft.Column( controls=[ - DigitButton(text="7"), - DigitButton(text="8"), - DigitButton(text="9"), - ActionButton(text="*"), + ft.Row( + controls=[self.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="="), + ] + ), ] - ), - ft.Row( - controls=[ - DigitButton(text="4"), - DigitButton(text="5"), - DigitButton(text="6"), - ActionButton(text="-"), - ] - ), - ft.Row( - controls=[ - DigitButton(text="1"), - DigitButton(text="2"), - DigitButton(text="3"), - ActionButton(text="+"), - ] - ), - ft.Row( - controls=[ - DigitButton(text="0", expand=2), - DigitButton(text="."), - ActionButton(text="="), - ] - ), - ] -), + ) ``` /// details | Full code @@ -329,19 +254,8 @@ page.add(calc1, calc2) ## Handling events Now let's make the calculator do its job. We will be using the same event handler -for all the buttons and use `data` property to differentiate between the actions -depending on the button clicked. For `CalcButton` class, let's specify `on_click=button_clicked` -event and set `data` property equal to button's text: - -```python -class CalcButton(ft.Button): - def __init__(self, text, button_clicked, expand=1): - super().__init__() - self.text = text - self.expand = expand - self.on_click = button_clicked - self.data = text -``` +for all the buttons and use `content` property to differentiate between the actions +depending on the button clicked. We will define `button_click` method in `CalculatorClass` and pass it to each button. Below is `on_click` event handler that will reset the Text value when "AC" button is clicked: diff --git a/sdk/python/packages/flet/integration_tests/tutorials/test_calculator.py b/sdk/python/packages/flet/integration_tests/tutorials/test_calculator.py new file mode 100644 index 0000000000..7ee8eb55d1 --- /dev/null +++ b/sdk/python/packages/flet/integration_tests/tutorials/test_calculator.py @@ -0,0 +1,73 @@ +import pytest + +import flet.testing as ftt + +# from examples.controls.checkbox import basic, handling_events, styled +from examples.tutorials.calculator import calc1 + +# @pytest.mark.asyncio(loop_scope="function") +# async def test_image_for_docs(flet_app_function: ftt.FletTestApp, request): +# flet_app_function.page.theme_mode = ft.ThemeMode.LIGHT +# await flet_app_function.assert_control_screenshot( +# request.node.name, +# ft.Column( +# intrinsic_width=True, +# controls=[ +# ft.Checkbox(), +# ft.Checkbox(label="Checked", value=True), +# ft.Checkbox(label="Disabled", disabled=True), +# ], +# ), +# ) + + +@pytest.mark.parametrize( + "flet_app_function", + [{"flet_app_main": calc1.main}], + indirect=True, +) +@pytest.mark.asyncio(loop_scope="function") +async def test_basic(flet_app_function: ftt.FletTestApp): + # button = await flet_app_function.tester.find_by_text("Submit") + # await flet_app_function.tester.tap(button) + await flet_app_function.tester.pump_and_settle() + flet_app_function.assert_screenshot( + "calc1", + await flet_app_function.take_page_controls_screenshot(), + ) + + +# @pytest.mark.parametrize( +# "flet_app_function", +# [{"flet_app_main": handling_events.main}], +# indirect=True, +# ) +# @pytest.mark.asyncio(loop_scope="function") +# async def test_handling_events(flet_app_function: ftt.FletTestApp): +# checkbox = await flet_app_function.tester.find_by_text( +# "Checkbox with 'change' event" +# ) +# await flet_app_function.tester.tap(checkbox) +# await flet_app_function.tester.pump_and_settle() +# await flet_app_function.tester.tap(checkbox) +# await flet_app_function.tester.pump_and_settle() +# await flet_app_function.tester.tap(checkbox) +# await flet_app_function.tester.pump_and_settle() +# scr = await flet_app_function.wrap_page_controls_in_screenshot() +# flet_app_function.assert_screenshot( +# "handling_events", +# await scr.capture(pixel_ratio=flet_app_function.screenshots_pixel_ratio), +# ) + + +# @pytest.mark.parametrize( +# "flet_app_function", +# [{"flet_app_main": styled.main}], +# indirect=True, +# ) +# @pytest.mark.asyncio(loop_scope="function") +# async def test_styled(flet_app_function: ftt.FletTestApp): +# flet_app_function.assert_screenshot( +# "styled_checkboxes", +# await flet_app_function.take_page_controls_screenshot(), +# ) From e2169733b9c675d3bd9baeb9da9965b882d93e9d Mon Sep 17 00:00:00 2001 From: InesaFitsner Date: Thu, 27 Nov 2025 11:40:18 -0800 Subject: [PATCH 09/11] Refactor calculator examples and update integration tests Added __init__.py to chip examples and updated main entry points to use '__name__ == "__main__"' guard. Improved calculator tutorial documentation for clarity. Enhanced integration tests for calculator examples, added golden screenshots for macOS, and expanded test coverage to include calc2 and calc3. --- sdk/python/examples/controls/chip/__init__.py | 0 .../examples/controls/chip/assist_chips.py | 3 +- .../examples/controls/chip/filter_chips.py | 3 +- .../examples/tutorials/calculator/calc3.py | 3 +- .../flet/docs/tutorials/calculator.md | 6 +- .../golden/macos/calculator/calc1.png | Bin 0 -> 55104 bytes .../golden/macos/calculator/calc2.png | Bin 0 -> 40357 bytes .../golden/macos/calculator/calc3.png | Bin 0 -> 30955 bytes .../tutorials/test_calculator.py | 100 ++++++++---------- 9 files changed, 56 insertions(+), 59 deletions(-) create mode 100644 sdk/python/examples/controls/chip/__init__.py create mode 100644 sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc1.png create mode 100644 sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc2.png create mode 100644 sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc3.png diff --git a/sdk/python/examples/controls/chip/__init__.py b/sdk/python/examples/controls/chip/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdk/python/examples/controls/chip/assist_chips.py b/sdk/python/examples/controls/chip/assist_chips.py index 7bcf78ca3f..188709c0cb 100644 --- a/sdk/python/examples/controls/chip/assist_chips.py +++ b/sdk/python/examples/controls/chip/assist_chips.py @@ -34,4 +34,5 @@ async def handle_chip2_click(e: ft.Event[ft.Chip]): ) -ft.run(main) +if __name__ == "__main__": + ft.run(main) diff --git a/sdk/python/examples/controls/chip/filter_chips.py b/sdk/python/examples/controls/chip/filter_chips.py index 16e84f61be..aaf1d71a3c 100644 --- a/sdk/python/examples/controls/chip/filter_chips.py +++ b/sdk/python/examples/controls/chip/filter_chips.py @@ -29,4 +29,5 @@ def handle_amenity_selection(e: ft.Event[ft.Chip]): ) -ft.run(main) +if __name__ == "__main__": + ft.run(main) diff --git a/sdk/python/examples/tutorials/calculator/calc3.py b/sdk/python/examples/tutorials/calculator/calc3.py index faf90fd3cf..90dd4ddf24 100644 --- a/sdk/python/examples/tutorials/calculator/calc3.py +++ b/sdk/python/examples/tutorials/calculator/calc3.py @@ -80,4 +80,5 @@ class ExtraActionButton(CalcButton): ) -ft.run(main) +if __name__ == "__main__": + ft.run(main) diff --git a/sdk/python/packages/flet/docs/tutorials/calculator.md b/sdk/python/packages/flet/docs/tutorials/calculator.md index 863e510610..effb53b34a 100644 --- a/sdk/python/packages/flet/docs/tutorials/calculator.md +++ b/sdk/python/packages/flet/docs/tutorials/calculator.md @@ -262,12 +262,14 @@ Below is `on_click` event handler that will reset the Text value when "AC" butto ```python def button_clicked(self, e): - if e.control.data == "AC": + data = e.control.content + print(f"Button clicked with data = {data}") + if data == "AC": self.result.value = "0" ``` With similar approach, `button_click` method will handle different calculator actions -depending on `data` property for each button. +depending on `content` property for each button. Copy the entire code for this step from [here](https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/calc/calc.py). diff --git a/sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc1.png b/sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc1.png new file mode 100644 index 0000000000000000000000000000000000000000..eda7ad147e54d4ccb2a5427151ba5c5bc9e87f2f GIT binary patch literal 55104 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�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 QykPC)%&bj|jR{x(1sSDR$N&HU literal 0 HcmV?d00001 diff --git a/sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc3.png b/sdk/python/packages/flet/integration_tests/tutorials/golden/macos/calculator/calc3.png new file mode 100644 index 0000000000000000000000000000000000000000..0469aa44cf37da36ec08db84024cb5f4b17fc797 GIT binary patch literal 30955 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 Date: Thu, 27 Nov 2025 13:25:27 -0800 Subject: [PATCH 10/11] Update calculator tutorial and example script Added a main guard to calc2.py to allow direct execution. Updated calculator tutorial documentation to use new image paths, correct code references, and improve clarity. --- sdk/python/examples/tutorials/calculator/calc2.py | 3 ++- .../packages/flet/docs/tutorials/calculator.md | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sdk/python/examples/tutorials/calculator/calc2.py b/sdk/python/examples/tutorials/calculator/calc2.py index f9fd00b8de..f32bf0113f 100644 --- a/sdk/python/examples/tutorials/calculator/calc2.py +++ b/sdk/python/examples/tutorials/calculator/calc2.py @@ -49,4 +49,5 @@ def main(page: ft.Page): ) -ft.run(main) +if __name__ == "__main__": + ft.run(main) diff --git a/sdk/python/packages/flet/docs/tutorials/calculator.md b/sdk/python/packages/flet/docs/tutorials/calculator.md index effb53b34a..cea46b0309 100644 --- a/sdk/python/packages/flet/docs/tutorials/calculator.md +++ b/sdk/python/packages/flet/docs/tutorials/calculator.md @@ -1,6 +1,7 @@ --- title: Calculator Tutorial examples: ../../examples/tutorials/calculator +example_images: ../test-images/tutorials/golden/macos/calculator --- In this tutorial you will learn, step-by-step, how to create a Calculator app in @@ -17,7 +18,6 @@ In this tutorial, we will cover all of the basic concepts for creating a Flet ap building a page layout, adding controls, making reusable UI components, handling events, and publishing options. -The tutorial consists of the following steps: ## Getting started with Flet @@ -62,7 +62,7 @@ Create `calc.py` with the following contents: Run the app and you should see a page like this: -{{ image("../examples/tutorials/calculator/media/app-1.png", alt="app-1", width="80%") }} +{{ image(example_images + "/calc1.png", alt="calc1", width="50%") }} ## Building page layout @@ -77,7 +77,7 @@ Replace `calc.py` contents with the following: Run the app and you should see a page like this: -{{ image("../examples/tutorials/calculator/media/app-2.png", alt="app-2", width="80%") }} +{{ image(example_images + "/calc2.png", alt="calc2", width="50%") }} ### Using Container for decoration @@ -162,7 +162,7 @@ We will be using these new classes now to create rows of buttons in the Containe content = ft.Column( controls=[ ft.Row( - controls=[self.result], + controls=[result], alignment=ft.MainAxisAlignment.END, ), ft.Row( @@ -216,7 +216,7 @@ content = ft.Column( ``` /// -{{ image("../examples/tutorials/calculator/media/app.png", alt="calc-app", width="80%") }} +{{ image(example_images + "/calc3.png", alt="calc3", width="50%") }} Just what we wanted! @@ -235,7 +235,7 @@ Flet apps with composability and reusability in mind. To make a reusable Calc app component, we are going to encapsulate its state and presentation logic in a separate `CalculatorApp` class. -Copy the entire code for this step from [here](https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/calc/calc4.py). +Copy the entire code for this step from [here](https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/calculator/calc4.py). /// admonition | Try something type: example @@ -271,7 +271,7 @@ def button_clicked(self, e): With similar approach, `button_click` method will handle different calculator actions depending on `content` property for each button. Copy the entire code for this step from -[here](https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/calc/calc.py). +[here](https://github.com/flet-dev/flet/blob/main/sdk/python/examples/tutorials/calculator/calc.py). Run the app and see it in the action: {{ image("../examples/tutorials/calculator/media/app.gif", alt="calc-app2", width="80%") }} From 6684820cfcfaa8e3112034e3d2577dba94c52e4a Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 1 Dec 2025 10:06:47 -0800 Subject: [PATCH 11/11] Add overloads to control decorator function Introduced @overload annotations for the control decorator to improve type hinting and clarify supported call signatures. --- .../flet/src/flet/controls/base_control.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sdk/python/packages/flet/src/flet/controls/base_control.py b/sdk/python/packages/flet/src/flet/controls/base_control.py index c87fd3a620..1e20cf879f 100644 --- a/sdk/python/packages/flet/src/flet/controls/base_control.py +++ b/sdk/python/packages/flet/src/flet/controls/base_control.py @@ -3,7 +3,7 @@ import logging import sys from dataclasses import InitVar, dataclass, field -from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union +from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union, overload from flet.controls.context import _context_page, context from flet.controls.control_event import ControlEvent, get_event_field_type @@ -40,6 +40,20 @@ def skip_field(): T = TypeVar("T", bound="BaseControl") +@overload +def control(cls: type[T]) -> type[T]: ... + + +@overload +def control( + dart_widget_name: Optional[Union[type[T], str]] = None, + *, + isolated: Optional[bool] = None, + post_init_args: int = 1, + **dataclass_kwargs: Any, +) -> Callable[[type[T]], type[T]]: ... + + @dataclass_transform() def control( dart_widget_name: Optional[Union[type[T], str]] = None,