Skip to content

Lezione 13: FilePicker, timer e media

  • Usare FilePicker per caricare file dal dispositivo
  • Selezionare immagini e mostrarle nell’app
  • Usare timer per eventi periodici
  • Creare un cronometro funzionante

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)
# Solo immagini
picker.pick_files(
allowed_extensions=["png", "jpg", "jpeg", "gif"],
allow_multiple=False,
)
# Solo PDF
picker.pick_files(
allowed_extensions=["pdf"],
allow_multiple=False,
)
# Più file
picker.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 come src.

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()

Flet non ha un timer built-in, ma possiamo usare threading.Timer di Python o il modulo time.

import threading
def esegui_dopo(secondi, funzione):
"""Esegue 'funzione' dopo 'secondi' secondi."""
timer = threading.Timer(secondi, funzione)
timer.daemon = True
timer.start()
import flet as ft
import 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.


import flet as ft
import threading
import 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)

import flet as ft
import threading
import 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)

import flet as ft
import threading
import 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)

ComponenteCodiceDescrizione
FilePickerft.FilePicker(on_result=f)Seleziona file dal dispositivo
pick filepicker.pick_files()Apre la finestra di selezione
estensioniallowed_extensions=["png","jpg"]Filtra per tipo file
Timerthreading.Timer(sec, func)Esegui dopo N secondi
Threadthreading.Thread(target=func)Esegui in parallelo
Sleeptime.sleep(sec)Aspetta N secondi

Crea un file sveglia.py che realizzi un’app con:

  1. Un campo input per inserire i minuti (es. 5)
  2. Un bottone “Avvia” che parte il conto alla rovescia
  3. Un display che mostra il tempo rimanente in formato MM:SS
  4. Allo scadere del tempo:
    • Mostra un AlertDialog con ”⏰ Tempo scaduto!”
    • Il dialogo ha un bottone “OK” per chiuderlo
  5. Un bottone “Stop” per fermare il timer prima che scada
  6. Un bottone “Reset” per tornare a 00:00
minuti = tempo_secondi // 60
secondi = tempo_secondi % 60
display = f"{minuti:02d}:{secondi:02d}"
  • Usa threading.Thread con time.sleep(1) per il countdown
  • Usa ft.AlertDialog per la notifica di scadenza
  • Disabilita il bottone “Avvia” mentre il timer è in esecuzione
  • Usa page.update() per aggiornare il display