Lezione 13: FilePicker, timer e media
Obiettivi
Section titled “Obiettivi”- Usare FilePicker per caricare file dal dispositivo
- Selezionare immagini e mostrarle nell’app
- Usare timer per eventi periodici
- Creare un cronometro funzionante
1. FilePicker — Caricare file
Section titled “1. FilePicker — Caricare file”FilePicker permette all’utente di selezionare file dal proprio computer.
import flet as ft
def main(page: ft.Page): page.title = "FilePicker" page.padding = 30
risultato = ft.Text("Nessun file selezionato")
def risultato_picker(e: ft.FilePickerResultEvent): if e.files: risultato.value = f"File: {e.files[0].name}\nPath: {e.files[0].path}" else: risultato.value = "Selezione annullata" page.update()
picker = ft.FilePicker(on_result=risultato_picker) page.overlay.append(picker) # Aggiunge il picker alla pagina (nascosto)
page.add( ft.ElevatedButton("📂 Seleziona file", on_click=lambda _: picker.pick_files()), risultato, )
ft.app(target=main)Tipi di file selezionabili
Section titled “Tipi di file selezionabili”# Solo immaginipicker.pick_files( allowed_extensions=["png", "jpg", "jpeg", "gif"], allow_multiple=False,)
# Solo PDFpicker.pick_files( allowed_extensions=["pdf"], allow_multiple=False,)
# Più filepicker.pick_files( allow_multiple=True, # Seleziona più file)2. FilePicker per immagini — Mostrare anteprima
Section titled “2. FilePicker per immagini — Mostrare anteprima”import flet as ft
def main(page: ft.Page): page.title = "Anteprima Immagine" page.padding = 30
immagine = ft.Image(width=400, height=300, visible=False)
def risultato_picker(e: ft.FilePickerResultEvent): if e.files: # Mostra l'immagine selezionata immagine.src = e.files[0].path immagine.visible = True page.update()
picker = ft.FilePicker(on_result=risultato_picker) page.overlay.append(picker)
page.add( ft.ElevatedButton("🖼️ Scegli immagine", on_click=lambda _: picker.pick_files( allowed_extensions=["png", "jpg", "jpeg", "gif"] )), immagine, )
ft.app(target=main)Nota:
picker.pick_files()restituisce il percorso del file sul computer. Per immagini, si usa direttamente comesrc.
Salvare immagini (opzionale)
Section titled “Salvare immagini (opzionale)”Per copiare l’immagine nella cartella del progetto:
import shutil
def risultato_picker(e): if e.files: file_sorgente = e.files[0].path nome_file = e.files[0].name destinazione = f"images/{nome_file}" shutil.copy(file_sorgente, destinazione) immagine.src = destinazione immagine.visible = True page.update()3. Timer e interval — Azioni periodiche
Section titled “3. Timer e interval — Azioni periodiche”Flet non ha un timer built-in, ma possiamo usare threading.Timer di Python o il modulo time.
Timer con threading
Section titled “Timer con threading”import threading
def esegui_dopo(secondi, funzione): """Esegue 'funzione' dopo 'secondi' secondi.""" timer = threading.Timer(secondi, funzione) timer.daemon = True timer.start()Esempio: messaggio dopo 3 secondi
Section titled “Esempio: messaggio dopo 3 secondi”import flet as ftimport threading
def main(page: ft.Page): page.title = "Timer" page.padding = 30
messaggio = ft.Text("")
def azione_timer(): messaggio.value = "⏰ Tempo scaduto!" page.update()
def avvia_timer(e): messaggio.value = "⏳ Timer di 3 secondi avviato..." page.update() threading.Timer(3.0, azione_timer).start()
page.add( ft.ElevatedButton("Avvia timer 3s", on_click=avvia_timer), messaggio, )
ft.app(target=main)⚠️ Attenzione: La funzione del timer viene eseguita in un thread separato. Per aggiornare la UI, chiama
page.update()dentro la funzione timer.
4. Cronometro funzionante
Section titled “4. Cronometro funzionante”import flet as ftimport threadingimport time
def main(page: ft.Page): page.title = "Cronometro" page.padding = 30
tempo = 0.0 in_esecuzione = False display = ft.Text("0.0", size=60, weight="bold")
def aggiorna_display(): display.value = f"{tempo:.1f}" page.update()
def loop_cronometro(): nonlocal tempo, in_esecuzione while in_esecuzione: time.sleep(0.1) tempo += 0.1 aggiorna_display()
def avvia(e): nonlocal in_esecuzione if not in_esecuzione: in_esecuzione = True threading.Thread(target=loop_cronometro, daemon=True).start()
def ferma(e): nonlocal in_esecuzione in_esecuzione = False
def resetta(e): nonlocal tempo, in_esecuzione in_esecuzione = False tempo = 0.0 aggiorna_display()
page.add( ft.Container( content=ft.Column([ ft.Text("⏱️ Cronometro", size=28, weight="bold"), display, ft.Row([ ft.ElevatedButton("▶️ Avvia", on_click=avvia, icon=ft.icons.PLAY_ARROW), ft.ElevatedButton("⏸️ Ferma", on_click=ferma, icon=ft.icons.PAUSE), ft.ElevatedButton("🔁 Resetta", on_click=resetta, icon=ft.icons.RESTART_ALT), ], alignment=ft.MainAxisAlignment.CENTER), ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), padding=30, bgcolor="white", border_radius=20, shadow=ft.BoxShadow(blur_radius=15, color=ft.colors.GREY_300), ), )
ft.app(target=main)5. Conto alla rovescia
Section titled “5. Conto alla rovescia”import flet as ftimport threadingimport time
def main(page: ft.Page): page.title = "Conto alla Rovescia" page.padding = 30
secondi_rimasti = 10 display = ft.Text("10", size=60, weight="bold") in_esecuzione = False
def aggiorna(): display.value = str(secondi_rimasti) page.update()
def loop_conto(): nonlocal secondi_rimasti, in_esecuzione while in_esecuzione and secondi_rimasti > 0: time.sleep(1) secondi_rimasti -= 1 aggiorna() if secondi_rimasti == 0: display.value = "🎉 Tempo scaduto!" in_esecuzione = False page.update()
def avvia_conto(e): nonlocal secondi_rimasti, in_esecuzione if not in_esecuzione: secondi_rimasti = 10 in_esecuzione = True threading.Thread(target=loop_conto, daemon=True).start()
page.add( ft.Text("⏳ Conto alla Rovescia", size=24, weight="bold"), display, ft.ElevatedButton("Avvia", on_click=avvia_conto), )
ft.app(target=main)6. Timer con input personalizzato
Section titled “6. Timer con input personalizzato”import flet as ftimport threadingimport time
def main(page: ft.Page): page.title = "Timer Personalizzato" page.padding = 30
input_secondi = ft.TextField( label="Secondi", hint_text="es. 30", value="10", width=100, keyboard_type=ft.KeyboardType.NUMBER, ) display = ft.Text("0", size=50, weight="bold") bottone = ft.ElevatedButton("▶️ Avvia", on_click=avvia_timer) in_esecuzione = False secondi_rimasti = 0
def aggiorna_display(): display.value = str(secondi_rimasti) page.update()
def loop(): nonlocal secondi_rimasti, in_esecuzione while in_esecuzione and secondi_rimasti > 0: time.sleep(1) secondi_rimasti -= 1 aggiorna_display() if secondi_rimasti == 0: display.value = "⏰ Tempo scaduto!" bottone.disabled = False in_esecuzione = False page.update()
def avvia_timer(e): nonlocal secondi_rimasti, in_esecuzione try: secondi_rimasti = int(input_secondi.value) in_esecuzione = True bottone.disabled = True threading.Thread(target=loop, daemon=True).start() except ValueError: display.value = "❌ Inserisci un numero valido" page.update()
page.add( ft.Text("⏱️ Timer", size=24, weight="bold"), ft.Row([input_secondi, ft.Text("secondi")]), display, bottone, )
ft.app(target=main)7. Tabella riassuntiva
Section titled “7. Tabella riassuntiva”| Componente | Codice | Descrizione |
|---|---|---|
| FilePicker | ft.FilePicker(on_result=f) | Seleziona file dal dispositivo |
| pick file | picker.pick_files() | Apre la finestra di selezione |
| estensioni | allowed_extensions=["png","jpg"] | Filtra per tipo file |
| Timer | threading.Timer(sec, func) | Esegui dopo N secondi |
| Thread | threading.Thread(target=func) | Esegui in parallelo |
| Sleep | time.sleep(sec) | Aspetta N secondi |
8. Esercizio autonomo
Section titled “8. Esercizio autonomo”🎯 Esercizio: “App Svegliamia”
Section titled “🎯 Esercizio: “App Svegliamia””Crea un file sveglia.py che realizzi un’app con:
- Un campo input per inserire i minuti (es. 5)
- Un bottone “Avvia” che parte il conto alla rovescia
- Un display che mostra il tempo rimanente in formato
MM:SS - Allo scadere del tempo:
- Mostra un AlertDialog con ”⏰ Tempo scaduto!”
- Il dialogo ha un bottone “OK” per chiuderlo
- Un bottone “Stop” per fermare il timer prima che scada
- Un bottone “Reset” per tornare a 00:00
Conversione tempo
Section titled “Conversione tempo”minuti = tempo_secondi // 60secondi = tempo_secondi % 60display = f"{minuti:02d}:{secondi:02d}"Suggerimenti
Section titled “Suggerimenti”- Usa
threading.Threadcontime.sleep(1)per il countdown - Usa
ft.AlertDialogper la notifica di scadenza - Disabilita il bottone “Avvia” mentre il timer è in esecuzione
- Usa
page.update()per aggiornare il display