Skip to content

Lezione 12: Dialoghi, feedback e componenti avanzati

  • Mostrare dialoghi di conferma e avviso
  • Usare SnackBar per notifiche temporanee
  • Usare BottomSheet per azioni contestuali
  • Costruire form con checkbox, switch, dropdown e date picker

AlertDialog mostra una finestra modale con un messaggio e bottoni.

import flet as ft
def main(page: ft.Page):
page.title = "AlertDialog"
page.padding = 30
def apri_dialogo(e):
# Crea il dialogo
dialog = ft.AlertDialog(
title=ft.Text("Conferma"),
content=ft.Text("Sei sicuro di voler procedere?"),
actions=[
ft.TextButton("Annulla", on_click=lambda e: chiudi_dialogo(dialog)),
ft.ElevatedButton("Conferma", on_click=lambda e: conferma(dialog)),
],
actions_alignment=ft.MainAxisAlignment.END,
)
page.dialog = dialog
dialog.open = True
page.update()
def chiudi_dialogo(dialog):
dialog.open = False
page.update()
def conferma(dialog):
dialog.open = False
page.snack_bar = ft.SnackBar(ft.Text("✅ Operazione confermata!"), open=True)
page.update()
page.add(
ft.ElevatedButton("Elimina elemento", on_click=apri_dialogo, icon=ft.icons.DELETE, color="red"),
)
ft.app(target=main)
ProprietàDescrizione
titleTitolo del dialogo
contentContenuto del dialogo
actionsLista di bottoni in fondo
actions_alignmentAllineamento bottoni
modalSe True, blocca interazione con la pagina
on_dismissFunzione chiamata alla chiusura
dialog = ft.AlertDialog(
modal=True, # L'utente DEVE rispondere
title=ft.Text("Attenzione!"),
content=ft.Text("Devi confermare per continuare."),
actions=[
ft.TextButton("OK", on_click=lambda e: chiudi(dialog)),
],
)

SnackBar mostra un messaggio in fondo alla pagina che scompare dopo qualche secondo.

page.snack_bar = ft.SnackBar(
content=ft.Text("✅ Salvato con successo!"),
open=True, # Mostra immediatamente
duration=3000, # Durata in millisecondi (default: 4000)
bgcolor="green", # Colore sfondo
behavior=ft.SnackBarBehavior.FLOATING, # Fluttuante o fisso in basso
)
page.update()
def mostra_snackbar(page, messaggio, colore="green"):
page.snack_bar = ft.SnackBar(
content=ft.Text(messaggio),
open=True,
bgcolor=colore,
duration=3000,
)
page.update()
# Uso:
mostra_snackbar(page, "✅ Operazione riuscita!", "green")
mostra_snackbar(page, "❌ Errore!", "red")
mostra_snackbar(page, "ℹ️ Informazione", "blue")
mostra_snackbar(page, "⚠️ Attenzione!", "orange")

BottomSheet è un pannello che scivola dal basso, tipico per menu di azioni.

import flet as ft
def main(page: ft.Page):
page.title = "BottomSheet"
page.padding = 30
def apri_foglio(e):
foglio = ft.BottomSheet(
content=ft.Container(
content=ft.Column([
ft.Text("Azioni disponibili", size=20, weight="bold"),
ft.Divider(),
ft.ListTile(
leading=ft.Icon(ft.icons.EDIT),
title=ft.Text("Modifica"),
on_click=lambda e: azione("Modifica"),
),
ft.ListTile(
leading=ft.Icon(ft.icons.SHARE),
title=ft.Text("Condividi"),
on_click=lambda e: azione("Condividi"),
),
ft.ListTile(
leading=ft.Icon(ft.icons.DELETE, color="red"),
title=ft.Text("Elimina", color="red"),
on_click=lambda e: azione("Elimina"),
),
]),
padding=20,
),
open=True,
)
page.dialog = foglio
page.update()
def azione(testo):
page.dialog.open = False
mostra_snackbar(f"Hai scelto: {testo}")
page.update()
def mostra_snackbar(msg):
page.snack_bar = ft.SnackBar(ft.Text(msg), open=True)
page.update()
page.add(
ft.ElevatedButton("Mostra azioni", on_click=apri_foglio),
)
ft.app(target=main)

def cambia_checkbox(e):
if e.control.value:
mostra_snackbar("✅ Accettato")
else:
mostra_snackbar("❌ Non accettato")
ft.Checkbox(
label="Accetto i termini e condizioni",
value=False,
on_change=cambia_checkbox,
)
def cambia_switch(e):
if e.control.value:
testo_notifiche.value = "Notifiche: ATTIVE"
else:
testo_notifiche.value = "Notifiche: DISATTIVATE"
page.update()
ft.Row([
ft.Text("Attiva notifiche"),
ft.Switch(
value=True,
on_change=cambia_switch,
),
])

def cambia_classe(e):
valore = e.control.value
mostra_snackbar(f"Hai selezionato: {valore}")
ft.Dropdown(
label="Seleziona la tua classe",
hint_text="Scegli...",
options=[
ft.dropdown.Option("4A"),
ft.dropdown.Option("4B"),
ft.dropdown.Option("4C"),
ft.dropdown.Option("4D"),
],
on_change=cambia_classe,
width=300,
)

DatePicker apre un calendario per selezionare una data:

import datetime
def main(page: ft.Page):
page.title = "DatePicker"
page.padding = 30
data_selezionata = ft.Text("Nessuna data selezionata", color="grey")
def apri_calendario(e):
def data_scelta(e):
data_selezionata.value = f"Data: {picker.value}"
data_selezionata.color = "black"
page.update()
picker = ft.DatePicker(
value=datetime.date.today(),
first_date=datetime.date(2020, 1, 1),
last_date=datetime.date(2030, 12, 31),
on_change=data_scelta,
)
page.overlay.append(picker)
picker.open = True
page.update()
page.add(
ft.ElevatedButton("Seleziona data", on_click=apri_calendario, icon=ft.icons.CALENDAR_MONTH),
data_selezionata,
)
ft.app(target=main)

7. Esempio guidato: Form registrazione completo

Section titled “7. Esempio guidato: Form registrazione completo”
import flet as ft
def main(page: ft.Page):
page.title = "Registrazione"
page.padding = 30
page.scroll = ft.ScrollMode.AUTO
def mostra_snack(msg, colore="green"):
page.snack_bar = ft.SnackBar(ft.Text(msg), open=True, bgcolor=colore)
page.update()
def registra(e):
# Validazione
if not nome.value:
mostra_snack("❌ Inserisci il nome", "red")
return
if not email.value or "@" not in email.value:
mostra_snack("❌ Email non valida", "red")
return
if not accetta_termini.value:
mostra_snack("❌ Devi accettare i termini", "red")
return
# Mostra riepilogo
mostra_snack(f"✅ Registrato! Classe: {classe.value}")
page.add(
ft.Container(
content=ft.Column([
ft.Text("📋 Riepilogo:", weight="bold", size=18),
ft.Text(f"Nome: {nome.value}"),
ft.Text(f"Email: {email.value}"),
ft.Text(f"Classe: {classe.value}"),
ft.Text(f"Notifiche: {'SI' if notifiche.value else 'NO'}"),
]),
padding=15, bgcolor="#e8f5e9", border_radius=10,
)
)
nome = ft.TextField(label="Nome completo", prefix_icon=ft.icons.PERSON)
email = ft.TextField(label="Email", prefix_icon=ft.icons.EMAIL)
classe = ft.Dropdown(
label="Classe",
options=[
ft.dropdown.Option("4A"),
ft.dropdown.Option("4B"),
ft.dropdown.Option("4C"),
],
width=200,
)
notifiche = ft.Switch(label="Ricevi notifiche", value=True)
accetta_termini = ft.Checkbox(label="Accetto i termini e condizioni", value=False)
page.add(
ft.Text("📝 Registrazione", size=28, weight="bold"),
ft.Divider(),
nome, email, classe,
notifiche, accetta_termini,
ft.Divider(),
ft.ElevatedButton("Registrati", on_click=registra, icon=ft.icons.CHECK),
)
ft.app(target=main)

ComponenteUsoEvento principale
AlertDialogConferme, avvisiBottoni nelle actions
SnackBarNotifiche temporaneeopen=True
BottomSheetMenu azioni dal bassoopen=True
CheckboxScelta binariaon_change
SwitchOn/Offon_change
DropdownSelezione da listaon_change
DatePickerSelezione dataon_change

Crea un file sondaggio.py che realizzi un’app per creare e votare sondaggi:

  1. Un form per creare un nuovo sondaggio:

    • Titolo (TextField)
    • Domanda (TextField)
    • 4 opzioni (TextField ciascuna)
    • Bottone “Crea sondaggio”
  2. Il sondaggio creato viene mostrato sotto forma di card:

    • Titolo e domanda
    • 4 opzioni con radio button (o checkbox)
    • Bottone “Vota” → mostra SnackBar con “Voto registrato!”
  3. Requisiti tecnici:

    • Usa AlertDialog per confermare la creazione del sondaggio
    • Usa SnackBar per feedback
    • Salva i sondaggi su file JSON
    • Mostra il numero di voti per ogni opzione
  • Usa ft.RadioGroup e ft.Radio per le opzioni di voto
  • Struttura dati: {"titolo": "...", "domanda": "...", "opzioni": [{"testo": "...", "voti": 0}, ...]}
  • Per salvare: usa json.dump() su sondaggi.json
  • Per le radio: ft.RadioGroup(content=ft.Column([ft.Radio(value="0", label="Opzione 1"), ...]))