Skip to content

Commit 44a81f2

Browse files
Update Calculator tutorial (#5864)
* 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. * 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. * Update calc3_dataclasses.py * 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. * 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. * 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. * 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. * 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. * 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. * 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. * Add overloads to control decorator function Introduced @overload annotations for the control decorator to improve type hinting and clarify supported call signatures. --------- Co-authored-by: Feodor Fitsner <feodor@appveyor.com>
1 parent 52cf738 commit 44a81f2

File tree

16 files changed

+368
-387
lines changed

16 files changed

+368
-387
lines changed

sdk/python/examples/controls/chip/__init__.py

Whitespace-only changes.

sdk/python/examples/controls/chip/assist_chips.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ async def handle_chip2_click(e: ft.Event[ft.Chip]):
3434
)
3535

3636

37-
ft.run(main)
37+
if __name__ == "__main__":
38+
ft.run(main)

sdk/python/examples/controls/chip/filter_chips.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ def handle_amenity_selection(e: ft.Event[ft.Chip]):
2929
)
3030

3131

32-
ft.run(main)
32+
if __name__ == "__main__":
33+
ft.run(main)

sdk/python/examples/tutorials/calculator/__init__.py

Whitespace-only changes.

sdk/python/examples/tutorials/calculator/calc.py

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,93 @@
1+
from dataclasses import field
2+
13
import flet as ft
24

35

6+
@ft.control
47
class CalcButton(ft.Button):
5-
def __init__(self, text, button_clicked, expand=1):
6-
super().__init__()
7-
self.text = text
8-
self.expand = expand
9-
self.on_click = button_clicked
10-
self.data = text
8+
expand: int = field(default_factory=lambda: 1)
119

1210

11+
@ft.control
1312
class DigitButton(CalcButton):
14-
def __init__(self, text, button_clicked, expand=1):
15-
CalcButton.__init__(self, text, button_clicked, expand)
16-
self.bgcolor = ft.Colors.WHITE24
17-
self.color = ft.Colors.WHITE
13+
bgcolor: ft.Colors = ft.Colors.WHITE_24
14+
color: ft.Colors = ft.Colors.WHITE
1815

1916

17+
@ft.control
2018
class ActionButton(CalcButton):
21-
def __init__(self, text, button_clicked):
22-
CalcButton.__init__(self, text, button_clicked)
23-
self.bgcolor = ft.Colors.ORANGE
24-
self.color = ft.Colors.WHITE
19+
bgcolor: ft.Colors = ft.Colors.ORANGE
20+
color: ft.Colors = ft.Colors.WHITE
2521

2622

23+
@ft.control
2724
class ExtraActionButton(CalcButton):
28-
def __init__(self, text, button_clicked):
29-
CalcButton.__init__(self, text, button_clicked)
30-
self.bgcolor = ft.Colors.BLUE_GREY_100
31-
self.color = ft.Colors.BLACK
25+
bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100
26+
color: ft.Colors = ft.Colors.BLACK
3227

3328

29+
@ft.control
3430
class CalculatorApp(ft.Container):
35-
# application's root control (i.e. "view") containing all other controls
36-
def __init__(self):
37-
super().__init__()
31+
def init(self):
3832
self.reset()
39-
40-
self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)
4133
self.width = 350
4234
self.bgcolor = ft.Colors.BLACK
43-
self.border_radius = ft.border_radius.all(20)
35+
self.border_radius = ft.BorderRadius.all(20)
4436
self.padding = 20
37+
self.result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)
38+
4539
self.content = ft.Column(
4640
controls=[
47-
ft.Row(controls=[self.result], alignment="end"),
41+
ft.Row(
42+
controls=[self.result],
43+
alignment=ft.MainAxisAlignment.END,
44+
),
4845
ft.Row(
4946
controls=[
50-
ExtraActionButton(
51-
text="AC", button_clicked=self.button_clicked
52-
),
53-
ExtraActionButton(
54-
text="+/-", button_clicked=self.button_clicked
55-
),
56-
ExtraActionButton(text="%", button_clicked=self.button_clicked),
57-
ActionButton(text="/", button_clicked=self.button_clicked),
47+
ExtraActionButton(content="AC", on_click=self.button_clicked),
48+
ExtraActionButton(content="+/-", on_click=self.button_clicked),
49+
ExtraActionButton(content="%", on_click=self.button_clicked),
50+
ActionButton(content="/", on_click=self.button_clicked),
5851
]
5952
),
6053
ft.Row(
6154
controls=[
62-
DigitButton(text="7", button_clicked=self.button_clicked),
63-
DigitButton(text="8", button_clicked=self.button_clicked),
64-
DigitButton(text="9", button_clicked=self.button_clicked),
65-
ActionButton(text="*", button_clicked=self.button_clicked),
55+
DigitButton(content="7", on_click=self.button_clicked),
56+
DigitButton(content="8", on_click=self.button_clicked),
57+
DigitButton(content="9", on_click=self.button_clicked),
58+
ActionButton(content="*", on_click=self.button_clicked),
6659
]
6760
),
6861
ft.Row(
6962
controls=[
70-
DigitButton(text="4", button_clicked=self.button_clicked),
71-
DigitButton(text="5", button_clicked=self.button_clicked),
72-
DigitButton(text="6", button_clicked=self.button_clicked),
73-
ActionButton(text="-", button_clicked=self.button_clicked),
63+
DigitButton(content="4", on_click=self.button_clicked),
64+
DigitButton(content="5", on_click=self.button_clicked),
65+
DigitButton(content="6", on_click=self.button_clicked),
66+
ActionButton(content="-", on_click=self.button_clicked),
7467
]
7568
),
7669
ft.Row(
7770
controls=[
78-
DigitButton(text="1", button_clicked=self.button_clicked),
79-
DigitButton(text="2", button_clicked=self.button_clicked),
80-
DigitButton(text="3", button_clicked=self.button_clicked),
81-
ActionButton(text="+", button_clicked=self.button_clicked),
71+
DigitButton(content="1", on_click=self.button_clicked),
72+
DigitButton(content="2", on_click=self.button_clicked),
73+
DigitButton(content="3", on_click=self.button_clicked),
74+
ActionButton(content="+", on_click=self.button_clicked),
8275
]
8376
),
8477
ft.Row(
8578
controls=[
8679
DigitButton(
87-
text="0", expand=2, button_clicked=self.button_clicked
80+
content="0", expand=2, on_click=self.button_clicked
8881
),
89-
DigitButton(text=".", button_clicked=self.button_clicked),
90-
ActionButton(text="=", button_clicked=self.button_clicked),
82+
DigitButton(content=".", on_click=self.button_clicked),
83+
ActionButton(content="=", on_click=self.button_clicked),
9184
]
9285
),
9386
]
9487
)
9588

9689
def button_clicked(self, e):
97-
data = e.control.data
90+
data = e.control.content
9891
print(f"Button clicked with data = {data}")
9992
if self.result.value == "Error" or data == "AC":
10093
self.result.value = "0"

sdk/python/examples/tutorials/calculator/calc1.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,27 @@ def main(page: ft.Page):
77

88
page.add(
99
result,
10-
ft.Button(text="AC"),
11-
ft.Button(text="+/-"),
12-
ft.Button(text="%"),
13-
ft.Button(text="/"),
14-
ft.Button(text="7"),
15-
ft.Button(text="8"),
16-
ft.Button(text="9"),
17-
ft.Button(text="*"),
18-
ft.Button(text="4"),
19-
ft.Button(text="5"),
20-
ft.Button(text="6"),
21-
ft.Button(text="-"),
22-
ft.Button(text="1"),
23-
ft.Button(text="2"),
24-
ft.Button(text="3"),
25-
ft.Button(text="+"),
26-
ft.Button(text="0"),
27-
ft.Button(text="."),
28-
ft.Button(text="="),
10+
ft.Button("AC"),
11+
ft.Button("+/-"),
12+
ft.Button("%"),
13+
ft.Button("/"),
14+
ft.Button("7"),
15+
ft.Button("8"),
16+
ft.Button("9"),
17+
ft.Button("*"),
18+
ft.Button("4"),
19+
ft.Button("5"),
20+
ft.Button("6"),
21+
ft.Button("-"),
22+
ft.Button("1"),
23+
ft.Button("2"),
24+
ft.Button("3"),
25+
ft.Button("+"),
26+
ft.Button("0"),
27+
ft.Button("."),
28+
ft.Button("="),
2929
)
3030

3131

32-
ft.run(main)
32+
if __name__ == "__main__":
33+
ft.run(main)

sdk/python/examples/tutorials/calculator/calc2.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,45 @@ def main(page: ft.Page):
99
ft.Row(controls=[result]),
1010
ft.Row(
1111
controls=[
12-
ft.Button(text="AC"),
13-
ft.Button(text="+/-"),
14-
ft.Button(text="%"),
15-
ft.Button(text="/"),
12+
ft.Button("AC"),
13+
ft.Button("+/-"),
14+
ft.Button("%"),
15+
ft.Button("/"),
1616
]
1717
),
1818
ft.Row(
1919
controls=[
20-
ft.Button(text="7"),
21-
ft.Button(text="8"),
22-
ft.Button(text="9"),
23-
ft.Button(text="*"),
20+
ft.Button("7"),
21+
ft.Button("8"),
22+
ft.Button("9"),
23+
ft.Button("*"),
2424
]
2525
),
2626
ft.Row(
2727
controls=[
28-
ft.Button(text="4"),
29-
ft.Button(text="5"),
30-
ft.Button(text="6"),
31-
ft.Button(text="-"),
28+
ft.Button("4"),
29+
ft.Button("5"),
30+
ft.Button("6"),
31+
ft.Button("-"),
3232
]
3333
),
3434
ft.Row(
3535
controls=[
36-
ft.Button(text="1"),
37-
ft.Button(text="2"),
38-
ft.Button(text="3"),
39-
ft.Button(text="+"),
36+
ft.Button("1"),
37+
ft.Button("2"),
38+
ft.Button("3"),
39+
ft.Button("+"),
4040
]
4141
),
4242
ft.Row(
4343
controls=[
44-
ft.Button(text="0"),
45-
ft.Button(text="."),
46-
ft.Button(text="="),
44+
ft.Button("0"),
45+
ft.Button("."),
46+
ft.Button("="),
4747
]
4848
),
4949
)
5050

5151

52-
ft.run(main)
52+
if __name__ == "__main__":
53+
ft.run(main)
Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,84 @@
1+
from dataclasses import field
2+
13
import flet as ft
24

35

46
def main(page: ft.Page):
57
page.title = "Calc App"
68
result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)
79

10+
@ft.control
811
class CalcButton(ft.Button):
9-
def __init__(self, text, expand=1):
10-
super().__init__()
11-
self.text = text
12-
self.expand = expand
12+
expand: int = field(default_factory=lambda: 1)
1313

14+
@ft.control
1415
class DigitButton(CalcButton):
15-
def __init__(self, text, expand=1):
16-
CalcButton.__init__(self, text, expand)
17-
self.bgcolor = ft.Colors.WHITE24
18-
self.color = ft.Colors.WHITE
16+
bgcolor: ft.Colors = ft.Colors.WHITE_24
17+
color: ft.Colors = ft.Colors.WHITE
1918

19+
@ft.control
2020
class ActionButton(CalcButton):
21-
def __init__(self, text):
22-
CalcButton.__init__(self, text)
23-
self.bgcolor = ft.Colors.ORANGE
24-
self.color = ft.Colors.WHITE
21+
bgcolor: ft.Colors = ft.Colors.ORANGE
22+
color: ft.Colors = ft.Colors.WHITE
2523

24+
@ft.control
2625
class ExtraActionButton(CalcButton):
27-
def __init__(self, text):
28-
CalcButton.__init__(self, text)
29-
self.bgcolor = ft.Colors.BLUE_GREY_100
30-
self.color = ft.Colors.BLACK
26+
bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100
27+
color: ft.Colors = ft.Colors.BLACK
3128

3229
page.add(
3330
ft.Container(
3431
width=350,
3532
bgcolor=ft.Colors.BLACK,
36-
border_radius=ft.border_radius.all(20),
33+
border_radius=ft.BorderRadius.all(20),
3734
padding=20,
3835
content=ft.Column(
3936
controls=[
40-
ft.Row(controls=[result], alignment="end"),
37+
ft.Row(controls=[result], alignment=ft.MainAxisAlignment.END),
4138
ft.Row(
4239
controls=[
43-
ExtraActionButton(text="AC"),
44-
ExtraActionButton(text="+/-"),
45-
ExtraActionButton(text="%"),
46-
ActionButton(text="/"),
40+
ExtraActionButton(content="AC"),
41+
ExtraActionButton(content="+/-"),
42+
ExtraActionButton(content="%"),
43+
ActionButton(content="/"),
4744
]
4845
),
4946
ft.Row(
5047
controls=[
51-
DigitButton(text="7"),
52-
DigitButton(text="8"),
53-
DigitButton(text="9"),
54-
ActionButton(text="*"),
48+
DigitButton(content="7"),
49+
DigitButton(content="8"),
50+
DigitButton(content="9"),
51+
ActionButton(content="*"),
5552
]
5653
),
5754
ft.Row(
5855
controls=[
59-
DigitButton(text="4"),
60-
DigitButton(text="5"),
61-
DigitButton(text="6"),
62-
ActionButton(text="-"),
56+
DigitButton(content="4"),
57+
DigitButton(content="5"),
58+
DigitButton(content="6"),
59+
ActionButton(content="-"),
6360
]
6461
),
6562
ft.Row(
6663
controls=[
67-
DigitButton(text="1"),
68-
DigitButton(text="2"),
69-
DigitButton(text="3"),
70-
ActionButton(text="+"),
64+
DigitButton(content="1"),
65+
DigitButton(content="2"),
66+
DigitButton(content="3"),
67+
ActionButton(content="+"),
7168
]
7269
),
7370
ft.Row(
7471
controls=[
75-
DigitButton(text="0", expand=2),
76-
DigitButton(text="."),
77-
ActionButton(text="="),
78-
]
72+
DigitButton(content="0", expand=2),
73+
DigitButton(content="."),
74+
ActionButton(content="="),
75+
],
7976
),
8077
]
8178
),
8279
)
8380
)
8481

8582

86-
ft.run(main)
83+
if __name__ == "__main__":
84+
ft.run(main)

0 commit comments

Comments
 (0)