Lezione 3: Layout — Row, Column, Container
Obiettivi
Section titled “Obiettivi”- Capire la differenza tra Row e Column
- Usare Container per organizzare e decorare sezioni
- Gestire allineamento, spaziatura e dimensioni
- Costruire layout complessi combinando i contenitori
1. Il problema del layout
Section titled “1. Il problema del layout”Finora abbiamo aggiunto componenti con page.add() uno dopo l’altro, in verticale. Per creare interfacce professionali dobbiamo organizzare i componenti.
Flet mette a disposizione tre strumenti principali:
| Componente | Funzione | Direzione |
|---|---|---|
Row | Dispone i figli in riga (orizzontale) | ➡️ |
Column | Dispone i figli in colonna (verticale) | ⬇️ |
Container | Avvolge un singolo figlio con decorazioni | — |
2. Row: disposizione orizzontale
Section titled “2. Row: disposizione orizzontale”Row dispone i suoi figli da sinistra a destra.
import flet as ft
def main(page: ft.Page): page.title = "Row" page.padding = 30
riga = ft.Row([ ft.Text("Uno"), ft.Text("Due"), ft.Text("Tre"), ])
page.add(riga)
ft.app(target=main)Proprietà di Row
Section titled “Proprietà di Row”| Proprietà | Descrizione | Valori esempi |
|---|---|---|
alignment | Allineamento verticale | MainAxisAlignment.START, CENTER, END |
vertical_alignment | Allineamento verticale | CrossAxisAlignment.START, CENTER, END |
spacing | Spazio tra i figli (pixel) | 10, 20, 50 |
wrap | Va a capo se non ci sta | True, False |
scroll | Scroll se troppo lungo | ft.ScrollMode.AUTO |
Esempio: allineamento
Section titled “Esempio: allineamento”import flet as ft
def main(page: ft.Page): page.padding = 30
page.add( ft.Text("Allineati a sinistra:", weight="bold"), ft.Row([ ft.ElevatedButton("Uno"), ft.ElevatedButton("Due"), ft.ElevatedButton("Tre"), ], alignment=ft.MainAxisAlignment.START),
ft.Text("Allineati al centro:", weight="bold"), ft.Row([ ft.ElevatedButton("Uno"), ft.ElevatedButton("Due"), ft.ElevatedButton("Tre"), ], alignment=ft.MainAxisAlignment.CENTER),
ft.Text("Allineati a destra:", weight="bold"), ft.Row([ ft.ElevatedButton("Uno"), ft.ElevatedButton("Due"), ft.ElevatedButton("Tre"), ], alignment=ft.MainAxisAlignment.END),
ft.Text("Spaziati (50px):", weight="bold"), ft.Row([ ft.Icon(ft.icons.STAR, color="amber"), ft.Icon(ft.icons.STAR, color="amber"), ft.Icon(ft.icons.STAR, color="amber"), ], spacing=50), )
ft.app(target=main)3. Column: disposizione verticale
Section titled “3. Column: disposizione verticale”Column dispone i suoi figli dall’alto verso il basso (come fa page.add()).
import flet as ft
def main(page: ft.Page): page.title = "Column" page.padding = 30
colonna = ft.Column([ ft.Text("Primo elemento"), ft.Text("Secondo elemento"), ft.Text("Terzo elemento"), ])
page.add(colonna)
ft.app(target=main)Proprietà di Column
Section titled “Proprietà di Column”| Proprietà | Descrizione | Valori esempi |
|---|---|---|
alignment | Allineamento verticale | MainAxisAlignment.START, CENTER, END, SPACE_BETWEEN |
horizontal_alignment | Allineamento orizzontale | CrossAxisAlignment.START, CENTER, END, STRETCH |
spacing | Spazio tra i figli (pixel) | 10, 20 |
scroll | Scroll se troppo lungo | ft.ScrollMode.AUTO |
Esempio: Column con allineamento
Section titled “Esempio: Column con allineamento”import flet as ft
def main(page: ft.Page): page.padding = 30
page.add( ft.Text("Colonna centrata:", weight="bold"), ft.Column([ ft.ElevatedButton("Bottone 1"), ft.ElevatedButton("Bottone 2"), ft.ElevatedButton("Bottone 3"), ], alignment=ft.MainAxisAlignment.CENTER), )
ft.app(target=main)4. Row DENTRO Column (e viceversa)
Section titled “4. Row DENTRO Column (e viceversa)”La vera potenza arriva combinando Row e Column.
import flet as ft
def main(page: ft.Page): page.title = "Layout combinato" page.padding = 30
# Card profilo card = ft.Container( content=ft.Column([ ft.Row([ ft.Icon(ft.icons.PERSON, size=50, color="blue"), ft.Column([ ft.Text("Mario Rossi", size=20, weight="bold"), ft.Text("Studente di Informatica", color="grey"), ]) ]), ft.Row([ ft.ElevatedButton("Modifica", icon=ft.icons.EDIT), ft.OutlinedButton("Elimina", icon=ft.icons.DELETE), ], alignment=ft.MainAxisAlignment.END), ]), padding=20, bgcolor="#f5f5f5", border_radius=10, width=400, )
page.add(card)
ft.app(target=main)Regola pratica: Row per disporre in orizzontale, Column per disporre in verticale. Row dentro Column crea righe dentro una struttura verticale.
5. Container: il decoratore
Section titled “5. Container: il decoratore”Container avvolge un singolo figlio e applica decorazioni.
ft.Container( content=ft.Text("Testo dentro un contenitore"), padding=20, # Spazio interno bgcolor="#e0e0e0", # Colore sfondo border_radius=10, # Angoli arrotondati width=300, # Larghezza height=200, # Altezza margin=10, # Margine esterno shadow=ft.BoxShadow(blur_radius=10, color="grey"), # Ombra border=ft.border.all(2, "blue"), # Bordo)Proprietà principali di Container
Section titled “Proprietà principali di Container”| Proprietà | Descrizione |
|---|---|
content | Il componente figlio (UNO SOLO) |
padding | Spazio interno (int o ft.padding.all(10)) |
margin | Spazio esterno (int o ft.margin.all(10)) |
bgcolor | Colore di sfondo |
border_radius | Angoli arrotondati |
width / height | Dimensioni fisse |
shadow | Ombra (ft.BoxShadow(...)) |
border | Bordo (ft.border.all(2, "color")) |
alignment | Allineamento del contenuto |
Esempio: card prodotto
Section titled “Esempio: card prodotto”import flet as ft
def main(page: ft.Page): page.title = "Card Prodotto" page.padding = 30
card = ft.Container( content=ft.Column([ ft.Icon(ft.icons.SHOPPING_BAG, size=60, color="purple"), ft.Text("Zaino Tech Pro", size=22, weight="bold"), ft.Text("Zaino impermeabile per laptop 15\"", color="grey"), ft.Row([ ft.Text("€ 49,99", size=24, weight="bold", color="green"), ft.ElevatedButton("Aggiungi", icon=ft.icons.SHOPPING_CART), ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN), ]), padding=20, bgcolor="white", border_radius=15, shadow=ft.BoxShadow(blur_radius=15, color=ft.colors.GREY_400), width=300, )
page.add(card)
ft.app(target=main)6. Esercizio guidato: Card profilo sociale
Section titled “6. Esercizio guidato: Card profilo sociale”Costruiamo insieme un profilo social-like:
import flet as ft
def main(page: ft.Page): page.title = "Profilo Social" page.bgcolor = "#e8f4f8" page.padding = 30 page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
# Card profilo card = ft.Container( content=ft.Column([ # Avatar + nome ft.Row([ ft.Container( content=ft.Icon(ft.icons.PERSON, size=60, color="white"), bgcolor="blue", width=80, height=80, border_radius=40, ), ft.Column([ ft.Text("Sofia Bianchi", size=22, weight="bold"), ft.Text("Sviluppatrice web", color="grey"), ], spacing=5), ], spacing=20),
ft.Divider(height=20), # Linea separatrice
# Statistiche ft.Row([ ft.Column([ft.Text("142", size=20, weight="bold"), ft.Text("Post", color="grey")], horizontal_alignment=ft.CrossAxisAlignment.CENTER), ft.Column([ft.Text("2.3K", size=20, weight="bold"), ft.Text("Follower", color="grey")], horizontal_alignment=ft.CrossAxisAlignment.CENTER), ft.Column([ft.Text("180", size=20, weight="bold"), ft.Text("Seguiti", color="grey")], horizontal_alignment=ft.CrossAxisAlignment.CENTER), ], alignment=ft.MainAxisAlignment.SPACE_AROUND),
ft.Divider(height=20),
# Bio ft.Text("Appassionata di tecnologia, musica e fotografia. Studio Informatica e sogno di creare app che cambiano il mondo.", italic=True, color="grey"),
ft.Divider(height=20),
# Bottoni azioni ft.Row([ ft.FilledButton("Segui", icon=ft.icons.PERSON_ADD), ft.OutlinedButton("Messaggio", icon=ft.icons.MESSAGE), ], alignment=ft.MainAxisAlignment.CENTER, spacing=20), ]), padding=25, bgcolor="white", border_radius=20, shadow=ft.BoxShadow(blur_radius=20, color=ft.colors.GREY_300), width=380, )
page.add(card)
ft.app(target=main)7. Riassunto dei comandi
Section titled “7. Riassunto dei comandi”| Comando | Cosa fa |
|---|---|
ft.Row([...]) | Componenti in orizzontale |
ft.Column([...]) | Componenti in verticale |
ft.Row(alignment=...) | Allinea orizzontalmente |
ft.Row(spacing=N) | Spazio tra i componenti |
ft.Container(content=..., padding=...) | Contenitore decorato |
ft.Container(bgcolor="...") | Sfondo del contenitore |
ft.Container(border_radius=N) | Angoli arrotondati |
ft.Container(shadow=...) | Ombra |
ft.Divider() | Linea di separazione |
8. Esercizio autonomo
Section titled “8. Esercizio autonomo”🎯 Esercizio: “Biglietto da visita aziendale”
Section titled “🎯 Esercizio: “Biglietto da visita aziendale””Crea un file biglietto_visita.py che realizzi un biglietto da visita con:
- Un Container principale che contenga tutto
- Nella parte superiore: logo aziendale a sinistra (usa un’icona), nome azienda a destra
- Al centro: nome e cognome del dipendente (grande), ruolo (grigio), una breve descrizione
- In fondo: riga con icona email + indirizzo email, icona telefono + numero
- Stile richiesto:
- Sfondo bianco con angoli arrotondati
- Ombra leggera
- Padding di 20px
- Larghezza massima 400px
Specifiche layout
Section titled “Specifiche layout”┌─────────────────────────────────┐│ [🏢] Nome Azienda S.r.l. ││─────────────────────────────────││ ││ Mario Verdi ││ Direttore Tecnico ││ "La qualità è il nostro motto" ││ ││─────────────────────────────────││ ✉️ mario@azienda.it 📞 345...│└─────────────────────────────────┘Suggerimenti
Section titled “Suggerimenti”- Usa
ft.Divider()per le linee di separazione - Per la riga in fondo con i contatti, usa
ft.Row(alignment=ft.MainAxisAlignment.SPACE_AROUND) - Per la citazione, usa
ft.Text(italic=True) - Gioca con
padding,spacingealignmentper ottenere l’effetto desiderato