Lezione 8: Tema, stili e immagini
Obiettivi
Section titled “Obiettivi”- Usare i temi predefiniti di Flet (chiaro/scuro)
- Personalizzare colori, font e stili globali
- Lavorare con immagini da web e locali
1. Tema chiaro e scuro
Section titled “1. Tema chiaro e scuro”Flet supporta nativamente i temi chiaro (light) e scuro (dark):
import flet as ft
def main(page: ft.Page): page.title = "Temi"
def cambia_tema(e): if page.theme_mode == ft.ThemeMode.LIGHT: page.theme_mode = ft.ThemeMode.DARK else: page.theme_mode = ft.ThemeMode.LIGHT page.update()
page.theme_mode = ft.ThemeMode.LIGHT # Tema iniziale
page.add( ft.Text("Prova il cambio tema!", size=24), ft.ElevatedButton("Cambia tema", on_click=cambia_tema), )
ft.app(target=main)2. Personalizzare il tema
Section titled “2. Personalizzare il tema”Puoi definire colori, font e stili globali con page.theme:
import flet as ft
def main(page: ft.Page): page.title = "Tema Personalizzato" page.padding = 30
# Tema personalizzato page.theme = ft.Theme( color_scheme=ft.ColorScheme( primary="blue", # Colore principale secondary="purple", # Colore secondario background="white", # Sfondo surface="#f5f5f5", # Superficie (card, ecc.) ), font_family="Arial", # Font globale )
# Tema scuro personalizzato page.dark_theme = ft.Theme( color_scheme=ft.ColorScheme( primary="lightblue", secondary="violet", background="#121212", surface="#1e1e1e", ), )
def cambia_tema(e): page.theme_mode = ft.ThemeMode.DARK if page.theme_mode == ft.ThemeMode.LIGHT else ft.ThemeMode.LIGHT page.update()
page.theme_mode = ft.ThemeMode.LIGHT
page.add( ft.Text("Tema Personalizzato", size=28, weight="bold", color=ft.colors.PRIMARY), ft.Text("Questo testo usa i colori del tema", color=ft.colors.SECONDARY), ft.ElevatedButton("Cambia tema", on_click=cambia_tema), )
ft.app(target=main)Colori del tema
Section titled “Colori del tema”| Colore | Uso |
|---|---|
ft.colors.PRIMARY | Colore principale (bottoni, barre) |
ft.colors.SECONDARY | Colore secondario (accenti) |
ft.colors.BACKGROUND | Sfondo della pagina |
ft.colors.SURFACE | Sfondo di card e superfici |
ft.colors.ERROR | Colore errori |
ft.colors.ON_PRIMARY | Testo su primary |
ft.colors.ON_SURFACE | Testo su surface |
3. Palette colori Material
Section titled “3. Palette colori Material”Flet include la palette Material Design completa:
# Colori standardft.colors.RED, ft.colors.BLUE, ft.colors.GREEN, ft.colors.AMBERft.colors.PURPLE, ft.colors.TEAL, ft.colors.PINK, ft.colors.ORANGE
# Variantift.colors.RED_100, ft.colors.RED_200, ..., ft.colors.RED_900ft.colors.RED_ACCENT_100, ft.colors.RED_ACCENT_200
# Colori utilitàft.colors.TRANSPARENTft.colors.WHITE, ft.colors.BLACKft.colors.GREY, ft.colors.GREY_300, ft.colors.GREY_6004. Immagini da web
Section titled “4. Immagini da web”ft.Image
Section titled “ft.Image”import flet as ft
def main(page: ft.Page): page.title = "Immagini" page.padding = 30
img = ft.Image( src="https://picsum.photos/400/300", # URL dell'immagine width=400, height=300, fit=ft.ImageFit.CONTAIN, # Come adattare l'immagine border_radius=15, # Angoli arrotondati )
page.add(img)
ft.app(target=main)Modalità di fit
Section titled “Modalità di fit”| Modalità | Descrizione |
|---|---|
ft.ImageFit.CONTAIN | Adatta mantenendo proporzioni (difetto) |
ft.ImageFit.COVER | Copre tutto lo spazio (può tagliare) |
ft.ImageFit.FILL | Riempie senza mantenere proporzioni |
ft.ImageFit.NONE | Dimensione originale |
Immagine cliccabile
Section titled “Immagine cliccabile”img = ft.Image( src="https://picsum.photos/400/300", width=400, height=300,)page.add( ft.GestureDetector( content=img, on_tap=lambda e: print("Immagine cliccata!"), ))5. Card prodotto con immagine
Section titled “5. Card prodotto con immagine”import flet as ft
def main(page: ft.Page): page.title = "Catalogo Prodotti" page.padding = 30 page.scroll = ft.ScrollMode.AUTO
page.theme = ft.Theme( color_scheme=ft.ColorScheme( primary="blue", secondary="amber", surface="#f8f9fa", ) )
prodotti = [ {"nome": "Laptop Pro", "prezzo": "€ 999", "img": "https://picsum.photos/seed/laptop/300/200"}, {"nome": "Smartphone X", "prezzo": "€ 599", "img": "https://picsum.photos/seed/phone/300/200"}, {"nome": "Cuffie Premium", "prezzo": "€ 149", "img": "https://picsum.photos/seed/headphones/300/200"}, ]
for p in prodotti: card = ft.Container( content=ft.Column([ ft.Image( src=p["img"], width=300, height=180, fit=ft.ImageFit.COVER, border_radius=ft.border_radius.only(top_left=10, top_right=10), ), ft.Container( content=ft.Row([ ft.Column([ ft.Text(p["nome"], size=18, weight="bold"), ft.Text(p["prezzo"], size=16, color=ft.colors.GREEN, weight="bold"), ]), ft.IconButton(ft.icons.SHOPPING_CART, icon_color="blue"), ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN), padding=15, ), ]), bgcolor="white", border_radius=10, shadow=ft.BoxShadow(blur_radius=10, color=ft.colors.GREY_300), width=300, margin=10, ) page.add(card)
ft.app(target=main)6. Immagini locali
Section titled “6. Immagini locali”Per immagini salvate sul computer:
# Metti l'immagine in una cartella 'images' accanto al tuo scriptft.Image( src="images/logo.png", width=200, height=200,)Oppure usa il percorso assoluto:
ft.Image( src="C:/Users/Studente/Desktop/logo.png", width=200, height=200,)7. Video come sfondo animato (opzionale)
Section titled “7. Video come sfondo animato (opzionale)”ft.Video( src="https://example.com/video.mp4", width=400, height=300, autoplay=True, loop=True, muted=True,)8. Esercizio autonomo
Section titled “8. Esercizio autonomo”🎯 Esercizio: “Galleria fotografica tematica”
Section titled “🎯 Esercizio: “Galleria fotografica tematica””Crea un file galleria_tematica.py che realizzi una galleria con:
- Tema personalizzato con colori a tua scelta (es. viola come primario)
- Un titolo “La Mia Galleria” con colore primary
- Una griglia (GridView) di immagini casuali da
https://picsum.photos/seed/NOME/300/200 - Almeno 6 immagini con seed diversi
- Sotto ogni immagine, un titolo (es. “Foto 1”, “Foto 2”, …)
- Ogni card deve avere:
- Angoli arrotondati
- Ombra
- Sfondo bianco
- Un bottone “Cambia tema” che alterna tra chiaro e scuro
Suggerimenti
Section titled “Suggerimenti”- Usa
https://picsum.photos/seed/{i}/300/200conida 1 a 6 per avere immagini diverse - Usa
GridView(max_extent=250, child_aspect_ratio=0.8) - Per la card con immagine + titolo:
ft.Column([ft.Image(...), ft.Text(titolo)]) - Ricorda che
page.theme_modesi cambia a runtime