11---
22title : Calculator Tutorial
3+ examples : ../../examples/tutorials/calculator
34---
45
56In this tutorial you will learn, step-by-step, how to create a Calculator app in
6- Python using
7- Flet framework and publish it as a desktop, mobile or web app.
7+ Python using Flet framework and publish it as a desktop, mobile or web app.
88The app is a simple console program, yet it is a multi-platform application with
99similar to iPhone calculator app UI:
1010
@@ -56,37 +56,8 @@ and a few [`Button`][flet.Button]s with all the numbers and actions on them.
5656
5757Create ` calc.py ` with the following contents:
5858
59- ``` python title="calc.py"
60- import flet as ft
61-
62- def main (page : ft.Page):
63- page.title = " Calc App"
64- result = ft.Text(value = " 0" )
65-
66- page.add(
67- result,
68- ft.Button(text = " AC" ),
69- ft.Button(text = " +/-" ),
70- ft.Button(text = " %" ),
71- ft.Button(text = " /" ),
72- ft.Button(text = " 7" ),
73- ft.Button(text = " 8" ),
74- ft.Button(text = " 9" ),
75- ft.Button(text = " *" ),
76- ft.Button(text = " 4" ),
77- ft.Button(text = " 5" ),
78- ft.Button(text = " 6" ),
79- ft.Button(text = " -" ),
80- ft.Button(text = " 1" ),
81- ft.Button(text = " 2" ),
82- ft.Button(text = " 3" ),
83- ft.Button(text = " +" ),
84- ft.Button(text = " 0" ),
85- ft.Button(text = " ." ),
86- ft.Button(text = " =" ),
87- )
88-
89- ft.run(main)
59+ ``` python
60+ -- 8 < -- " {{ examples }} /calc1.py"
9061```
9162
9263Run 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.
10071
10172Replace ` calc.py ` contents with the following:
10273
103- ``` python title="calc.py"
104- import flet as ft
105-
106-
107- def main (page : ft.Page):
108- page.title = " Calc App"
109- result = ft.Text(value = " 0" )
110-
111- page.add(
112- ft.Row(controls = [result]),
113- ft.Row(
114- controls = [
115- ft.Button(text = " AC" ),
116- ft.Button(text = " +/-" ),
117- ft.Button(text = " %" ),
118- ft.Button(text = " /" ),
119- ]
120- ),
121- ft.Row(
122- controls = [
123- ft.Button(text = " 7" ),
124- ft.Button(text = " 8" ),
125- ft.Button(text = " 9" ),
126- ft.Button(text = " *" ),
127- ]
128- ),
129- ft.Row(
130- controls = [
131- ft.Button(text = " 4" ),
132- ft.Button(text = " 5" ),
133- ft.Button(text = " 6" ),
134- ft.Button(text = " -" ),
135- ]
136- ),
137- ft.Row(
138- controls = [
139- ft.Button(text = " 1" ),
140- ft.Button(text = " 2" ),
141- ft.Button(text = " 3" ),
142- ft.Button(text = " +" ),
143- ]
144- ),
145- ft.Row(
146- controls = [
147- ft.Button(text = " 0" ),
148- ft.Button(text = " ." ),
149- ft.Button(text = " =" ),
150- ]
151- ),
152- )
153-
154- ft.run(main)
74+ ``` python
75+ -- 8 < -- " {{ examples }} /calc2.py"
15576```
15677
15778Run 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:
17596 ft.Container(
17697 width = 350 ,
17798 bgcolor = ft.Colors.BLACK ,
178- border_radius = ft.border_radius .all(20 ),
99+ border_radius = ft.BorderRadius .all(20 ),
179100 padding = 20 ,
180101 content = ft.Column(
181102 controls = [], # (1)!
@@ -196,91 +117,95 @@ result = ft.Text(value="0", color=ft.Colors.WHITE, size=20)
196117```
197118
198119For the buttons, if we look again at the UI we are aiming to achieve, there are 3 types of buttons:
120+
1991211 . ** Digit Buttons** . They have dark grey background color and white text, size is the same for all.
122+
2001232 . ** Action Buttons** . They have orange background color and white text, size is the same for all except ` 0 ` button which is twice as large.
124+
2011253 . ** Extra action buttons** . They have light grey background color and dark text, size is the same for all.
202126
203127The buttons will be used multiple time in the program, so we will be creating
204128custom [ Styled Controls] ( ../cookbook/custom-controls.md#styled-controls ) to reuse the code.
205129
206130Since all those types should inherit from ` Button ` class and have common ` text ` and ` expand ` properties, let's create a parent ` CalcButton ` class:
131+
207132``` python
133+ @ft.control
208134class CalcButton (ft .Button ):
209- def __init__ (self , text , expand = 1 ):
210- super ().__init__ ()
211- self .text = text
212- self .expand = expand
135+ expand: int = 1
213136```
214137
215138Now let's create child classes for all three types of buttons:
216139
217140``` python
141+ @ft.control
218142class DigitButton (CalcButton ):
219- def __init__ (self , text , expand = 1 ):
220- CalcButton.__init__ (self , text, expand)
221- self .bgcolor = ft.Colors.WHITE_24
222- self .color = ft.Colors.WHITE
143+ bgcolor: ft.Colors = ft.Colors.WHITE_24
144+ color: ft.Colors = ft.Colors.WHITE
145+
223146
147+ @ft.control
224148class ActionButton (CalcButton ):
225- def __init__ (self , text ):
226- CalcButton.__init__ (self , text)
227- self .bgcolor = ft.Colors.ORANGE
228- self .color = ft.Colors.WHITE
149+ bgcolor: ft.Colors = ft.Colors.ORANGE
150+ color: ft.Colors = ft.Colors.WHITE
229151
152+
153+ @ft.control
230154class ExtraActionButton (CalcButton ):
231- def __init__ (self , text ):
232- CalcButton.__init__ (self , text)
233- self .bgcolor = ft.Colors.BLUE_GREY_100
234- self .color = ft.Colors.BLACK
155+ bgcolor: ft.Colors = ft.Colors.BLUE_GREY_100
156+ color: ft.Colors = ft.Colors.BLACK
235157```
236158
237159We will be using these new classes now to create rows of buttons in the Container:
238160
239161``` python
240- content= ft.Column(
241- controls = [
242- ft.Row(controls = [result], alignment = " end" ),
243- ft.Row(
244- controls = [
245- ExtraActionButton(text = " AC" ),
246- ExtraActionButton(text = " +/-" ),
247- ExtraActionButton(text = " %" ),
248- ActionButton(text = " /" ),
249- ]
250- ),
251- ft.Row(
162+ content = ft.Column(
252163 controls = [
253- DigitButton(text = " 7" ),
254- DigitButton(text = " 8" ),
255- DigitButton(text = " 9" ),
256- ActionButton(text = " *" ),
164+ ft.Row(
165+ controls = [self .result],
166+ alignment = ft.MainAxisAlignment.END ,
167+ ),
168+ ft.Row(
169+ controls = [
170+ ExtraActionButton(content = " AC" ),
171+ ExtraActionButton(content = " +/-" ),
172+ ExtraActionButton(content = " %" ),
173+ ActionButton(content = " /" ),
174+ ]
175+ ),
176+ ft.Row(
177+ controls = [
178+ DigitButton(content = " 7" ),
179+ DigitButton(content = " 8" ),
180+ DigitButton(content = " 9" ),
181+ ActionButton(content = " *" ),
182+ ]
183+ ),
184+ ft.Row(
185+ controls = [
186+ DigitButton(content = " 4" ),
187+ DigitButton(content = " 5" ),
188+ DigitButton(content = " 6" ),
189+ ActionButton(content = " -" ),
190+ ]
191+ ),
192+ ft.Row(
193+ controls = [
194+ DigitButton(content = " 1" ),
195+ DigitButton(content = " 2" ),
196+ DigitButton(content = " 3" ),
197+ ActionButton(content = " +" ),
198+ ]
199+ ),
200+ ft.Row(
201+ controls = [
202+ DigitButton(content = " 0" , expand = 2 ),
203+ DigitButton(content = " ." ),
204+ ActionButton(content = " =" ),
205+ ]
206+ ),
257207 ]
258- ),
259- ft.Row(
260- controls = [
261- DigitButton(text = " 4" ),
262- DigitButton(text = " 5" ),
263- DigitButton(text = " 6" ),
264- ActionButton(text = " -" ),
265- ]
266- ),
267- ft.Row(
268- controls = [
269- DigitButton(text = " 1" ),
270- DigitButton(text = " 2" ),
271- DigitButton(text = " 3" ),
272- ActionButton(text = " +" ),
273- ]
274- ),
275- ft.Row(
276- controls = [
277- DigitButton(text = " 0" , expand = 2 ),
278- DigitButton(text = " ." ),
279- ActionButton(text = " =" ),
280- ]
281- ),
282- ]
283- ),
208+ )
284209```
285210
286211/// details | Full code
@@ -329,19 +254,8 @@ page.add(calc1, calc2)
329254## Handling events
330255
331256Now let's make the calculator do its job. We will be using the same event handler
332- for all the buttons and use ` data ` property to differentiate between the actions
333- depending on the button clicked. For ` CalcButton ` class, let's specify ` on_click=button_clicked `
334- event and set ` data ` property equal to button's text:
335-
336- ``` python
337- class CalcButton (ft .Button ):
338- def __init__ (self , text , button_clicked , expand = 1 ):
339- super ().__init__ ()
340- self .text = text
341- self .expand = expand
342- self .on_click = button_clicked
343- self .data = text
344- ```
257+ for all the buttons and use ` content ` property to differentiate between the actions
258+ depending on the button clicked.
345259
346260We will define ` button_click ` method in ` CalculatorClass ` and pass it to each button.
347261Below is ` on_click ` event handler that will reset the Text value when "AC" button is clicked:
0 commit comments