05 Sezione 5 di 15
Finestre e controlli
I programmi con le finestre sono fatti di controlli (pulsanti, caselle, elenchi…) e di eventi (un clic, un tasto, un valore che cambia). Qui impari a leggere e cambiare i controlli dal codice e a rispondere a ciò che fa l'utente.
Com'è fatto un progetto con le finestre#
Un progetto è una cartella. Per ogni finestra ci sono due file: la maschera (Finestra1.maschera), con i controlli e le loro proprietà, che disegni in Leo Studio, e il codice (Finestra1.leo), che scrivi tu. In più c'è progetto.toml, con il nome del progetto e la finestra da aprire all'avvio.
Il codice di una finestra è fatto soprattutto di gestori di eventi: pezzi di codice che partono quando succede qualcosa.
Gli eventi: quando … fai#
quando Finestra1.apertura fai Etichetta1.testo = "Benvenuto!"fine quando Timer1.scatto fai Orologio.testo = ora()fineEtichetta1.testo = "Benvenuto!"
quando Controllo.evento fai … fine si legge «quando il controllo riceve l'evento, fai…». Le regole:
- si scrive al livello più esterno del file, non dentro una funzione;
- per ogni coppia controllo-evento c'è un solo gestore;
- il modo più veloce per crearlo è il doppio clic sul controllo in Leo Studio (evento principale) o sull'evento nel pannello Proprietà;
- un errore dentro un gestore compare in una finestra con il messaggio completo, e il programma continua.
| Evento | Quando arriva |
|---|---|
apertura, chiusura | la finestra si apre / si chiude |
clic, doppio_clic | un clic del mouse sul controllo |
cambio | il valore cambia (casella di testo, casella di spunta, cursore…) |
invio | l'utente preme Invio in una casella |
selezione | si sceglie un elemento in un Elenco o in un MenuATendina |
tasto | un tasto premuto nella finestra |
scatto | il Timer è arrivato al suo intervallo |
ridimensionamento | la finestra cambia dimensioni |
I dati dell'evento#
Dentro un gestore esiste la variabile evento, un dizionario con i dati di ciò che è successo: per un clic la posizione (evento["x"], evento["y"]), per un cambio il nuovo valore (evento["valore"]), per una selezione evento["indice"] ed evento["elemento"].
quando Elenco1.selezione fai Etichetta1.testo = "Hai scelto {evento["elemento"]}"fine quando Finestra1.tasto fai se evento["ctrl"] e evento["tasto"] == "S" allora stampa("Hai premuto Ctrl+S") finefineHai premuto Ctrl+S Etichetta1.testo = "Hai scelto Milano"
I tasti hanno nomi italiani: le lettere maiuscole ("A"), le cifre, "F1"…"F12", "Invio", "Esc", "Spazio", "Tab", "Canc", "Sinistra", "Destra", "Su", "Giù"…
Leggere e cambiare le proprietà#
I controlli sono oggetti: con il punto leggi e cambi le loro proprietà e chiami i loro metodi.
quando Pulsante1.clic fai Elenco1.aggiungi("Voce {lunghezza(Elenco1.elementi) + 1}") Etichetta1.testo = "Nell'elenco ci sono {lunghezza(Elenco1.elementi)} voci" Etichetta1.colore_testo = "verde" aumenta Pulsante1.larghezza di 10 CasellaSpunta1.abilitato = falsofineEtichetta1.testo = "Nell'elenco ci sono 2 voci" Pulsante1.larghezza = 110 Elenco1.elementi = ["Voce 1", "Voce 2"]
Le proprietà che quasi tutti i controlli visibili hanno:
| Proprietà | Tipo | Significato |
|---|---|---|
testo | testo | la scritta del controllo (per la finestra, il titolo) |
sinistra, alto | intero | posizione in pixel dall'angolo in alto a sinistra |
larghezza, altezza | intero | dimensioni in pixel |
visibile | logico | se falso il controllo non si vede |
abilitato | logico | se falso non risponde a mouse e tastiera |
suggerimento | testo | il fumetto che compare passandoci sopra |
colore_testo, colore_sfondo | colore | "" = colore predefinito (la finestra ha sfondo) |
carattere, dimensione_carattere | testo, intero | tipo e grandezza delle lettere |
opacità | intero | da 0 (invisibile) a 100 (pieno) |
ancoraggio | lista | i bordi a cui il controllo resta agganciato quando la finestra si allarga |
Leo capisce anche alcuni nomi alternativi naturali: colore, scritta, titolo, x, y, e non fa caso alle maiuscole o agli accenti (Pulsante1.Testo, opacita). Se scrivi una proprietà che non esiste, l'errore elenca quelle disponibili.
Ogni controllo ha anche le sue proprietà speciali: un Elenco ha elementi e indice_selezionato, un Timer ha intervallo (in millisecondi) e attivo, una BarraAvanzamento ha valore, minimo e massimo. Le trovi tutte nel pannello Proprietà di Leo Studio.
Nome e testo: l'errore più comune#
Nel codice si usa il nome del controllo (Etichetta1), non il suo tipo (Etichetta) e non la scritta che mostra. Anche le maiuscole contano: il controllo si chiama Pulsante1, non pulsante1.
etichetta.testo = "Ciao" # "etichetta" è il tipo, non il nomeLeo se ne accorge e spiega: «etichetta è il tipo di controllo, non il suo nome: nella finestra c'è Etichetta1. Scrivi Etichetta1.testo.»; la correzione automatica propone il nome giusto.
Messaggi, domande e più finestre#
| Funzione | Che cosa fa |
|---|---|
messaggio(testo) | una finestrella con il testo e il pulsante OK |
domanda(testo) | una finestrella Sì/No: restituisce vero o falso |
apri_finestra("Finestra2") | mostra un'altra finestra del progetto |
chiudi_finestra("Finestra2") | la chiude; chiudere la finestra iniziale termina il programma |
attendi(secondi) | aspetta, senza bloccare la finestra |
quando PulsanteElimina.clic fai se domanda("Vuoi davvero svuotare l'elenco?") allora Elenco1.svuota() messaggio("Fatto!") finefine[Leo] Vuoi davvero svuotare l'elenco? [s/n] s
[Leo] Fatto!
Elenco1.elementi = []Ogni finestra vede i controlli di tutte le altre finestre del progetto.
Colori#
Un colore si scrive in quattro modi: un nome italiano ("rosso", "grigio_scuro", "blu_notte"…), un codice "#E0182D", i tre numeri da 0 a 255 con rgb(255, 136, 0), oppure, per comodità, un nome senza virgolette (Finestra1.sfondo = nero). "" torna al colore predefinito.
quando Finestra1.apertura fai Finestra1.sfondo = "blu_notte" Etichetta1.colore_testo = "#F2CF7A" Pulsante1.colore_sfondo = rgb(255, 136, 0)fineFinestra1.sfondo = "#191970" Etichetta1.colore_testo = "#F2CF7A" Pulsante1.colore_sfondo = "#FF8800"
I nomi italiani sono 55, da nero, antracite e grafite fino a indaco, viola, lilla, lavanda e trasparente: in Leo Studio li trovi tutti nella Tavolozza.
L'aspetto della finestra#
La finestra può avere quasi ogni aspetto, anche una forma diversa dal rettangolo. Tutto si imposta dal pannello Proprietà o dal codice, anche mentre il programma gira.
| Forma | Da codice |
|---|---|
| rettangolo arrotondato | Finestra1.forma = "arrotondata" e Finestra1.raggio_angoli = 24 |
| cerchio, ellisse | Finestra1.forma = "cerchio" |
| poligono regolare | Finestra1.forma = forma_poligono(6) |
| stella | Finestra1.forma = forma_stella(5) |
| da un'immagine PNG | Finestra1.forma = forma_immagine("gatto.png") |
Altre proprietà della finestra: opacità, bordo ("nessuno", "linea", "doppio", "luminoso"), ombra, barra_titolo, sempre_in_primo_piano, ridimensionabile, icona, animazione_apertura e animazione_chiusura ("dissolvenza", "zoom", "scorrimento", "rimbalzo").
Con tema_controlli scegli l'aspetto di pulsanti, caselle e menu: "moderno" (predefinito), "classico" (come il vecchio Windows), "piatto" o "futuristico" (nero e rosso, come Leo Studio).
Stili pronti per pulsanti ed etichette#
Pulsante, PulsanteImmagine ed Etichetta hanno la proprietà stile, che dà colori, angoli, effetto al passaggio del mouse e al clic, sempre leggibili e coerenti con il tema della finestra.
| Stile | Quando usarlo |
|---|---|
"normale" | l'aspetto del tema (predefinito) |
"principale" | l'azione più importante della finestra |
"secondario" | le azioni di contorno |
"pericolo" | eliminare, annullare qualcosa di importante (rosso) |
"successo" | confermare, salvare (verde) |
"contorno" | solo il bordo e la scritta |
"testo" | solo la scritta, come un collegamento |
quando Finestra1.apertura fai PulsanteSalva.stile = "principale" PulsanteElimina.stile = "pericolo" Etichetta1.stile = "testo"finePulsanteSalva.stile = "principale" PulsanteElimina.stile = "pericolo"
Vanno bene anche dei sinonimi: "primario" per "principale", "elimina" per "pericolo", "ok" per "successo"…
Animazioni in una frase#
La frase anima porta pian piano una proprietà di un controllo a un nuovo valore: posizione, dimensioni, opacità, colori.
quando Pulsante1.clic fai anima Pulsante1.sinistra a 300 in 0.5 secondi anima Pulsante1.alto a 40 in 800 millisecondi con curva "rimbalzo" anima Etichetta1.colore_testo a "rosso"finePulsante1.sinistra = 300 Pulsante1.alto = 40 Etichetta1.colore_testo = "#FF0000"
La forma completa è anima Oggetto.proprietà a VALORE in DURATA secondi con curva "nome"; durata (predefinita 0,3 secondi) e curva sono facoltative. Le curve sono "morbida" (predefinita), "lineare", "veloce", "lenta", "rimbalzo" ed "elastica". L'animazione non ferma il programma, e una nuova animazione della stessa proprietà sostituisce quella in corso.
Ci sono anche cinque effetti pronti, come funzioni o come metodi del controllo: lampeggia, scuoti, pulsa, dissolvi e compari.
funzione mostra_benvenuto() Etichetta1.testo = "Benvenuto!"fine quando PulsanteAccedi.clic fai se CasellaPassword.testo != "segreta" allora CasellaPassword.scuoti() altrimenti dissolvi(PannelloAccesso, poi = mostra_benvenuto) finefineCon poi = funzione fai qualcosa quando l'animazione finisce. Se chi usa il programma ha scelto di ridurre le animazioni, ogni animazione salta subito allo stato finale: il programma funziona nello stesso modo. Tutti i dettagli sono nella sezione Grafici, suoni e animazioni.
Effetti senza codice e comandi degli effetti#
Nel pannello delle proprietà ogni controllo visibile ha il gruppo Effetti, per dare vita all'app senza scrivere codice: animazione_entrata (come compare quando si apre la finestra: "dissolvenza", "scorri_su", "zoom", "rimbalzo", "elastico", "caduta", "ruota", "capovolgi"...), con ritardo_entrata e durata_entrata in millisecondi per farli entrare uno dopo l'altro; effetto_continuo (un effetto che si ripete sempre: "pulsa", "respira", "galleggia", "oscilla", "ruota", "brilla", "arcobaleno", "battito"...) con la sua velocità_effetto; effetto_tocco (cosa fa quando lo tocchi: "rimbalzo", "affonda", "onda", "brilla"...). Nel disegnatore del telefono il pulsante Prova l'effetto li fa vedere subito.
Dal codice, ogni controllo visibile ha anche i comandi rimbalza(), ruota(giri), capovolgi(), brilla(), dondola(), trema(), vola_a(x, y), ingrandisci(fattore), cambia_colore(colore), cambia_sfondo(colore), mostra_con(effetto) e nascondi_con(effetto), tutti con poi = funzione.
quando PulsanteGioca.clic fai Palla.rimbalza(3) Stella.ruota(2) Titolo.cambia_colore("verde") Palla.vola_a(20, 400, 0.8, "rimbalzo")fine quando PulsanteNascondi.clic fai Cuore.nascondi_con("zoom")fineSul PC le rotazioni diventano un «giro di moneta» (Qt non ruota i controlli); con ridurre le animazioni gli effetti non si muovono. Un progetto d'esempio con tutti gli effetti è in esempi/controlli/effetti/.
I 146 controlli#
La barra dei controlli di Leo Studio ha 146 controlli in 21 categorie: i 40 «classici», come quelli di Visual Basic, quelli inventati per Leo, i 22 oggetti da gioco della scheda Giochi, i 20 di Tutti i giorni (calendario, chat, firma, PIN, carosello, meteo…) e quelli della scheda Telefono (bussola, livella, torcia, posizione, batteria, contapassi, fonometro, registratore…: vedi Leo sul telefono). In esempi/controlli/ c'è un progetto d'esempio per ogni categoria.
| Categoria | Controlli |
|---|---|
| Base | Finestra, Etichetta, Pulsante, PulsanteImmagine, Collegamento |
| Inserimento | CasellaTesto, CasellaPassword, AreaTesto, CasellaNumero, SelettoreData, SelettoreColore, Cursore |
| Scelta | CasellaSpunta, Scelta, Interruttore, Elenco, MenuATendina |
| Contenitori | Riquadro, Schede, PannelloScorrevole, Divisore |
| Visualizzazione | Immagine, BarraAvanzamento, BarraStato, Suggerimento |
| Dati | Tabella, Albero, Grafico |
| Disegno | Tela, Linea, Forma |
| Media | Suono, Video, Fotocamera, Dettatura, Voce, LettoreQR, GeneratoreQR, Galleria |
| Menu | BarraMenu, VoceMenu, MenuContestuale, BarraStrumenti |
| Invisibili | Timer, DialogoFile, Appunti |
| Italia | CasellaCodiceFiscale, CasellaIBAN, CasellaTarga, SelettoreComune, CasellaImporto, CalendarioFestività |
| Hardware | SchedaPico, Led, PulsanteFisico, Sensore, Oscilloscopio, PortaSeriale |
| Telefono | Bussola, Livella, Vibrazione, Torcia, Posizione, Batteria, Condivisione |
| Giochi | Scena, Sprite, Fisica, Joystick, Punteggio |
| Dati e rete | BancaDati, ModuloAutomatico, RichiestaWeb, ServerWeb, Mappa |
| Sicurezza | Cifratura, MisuratorePassword, Registro |
| Produttività | Lavagna, Kanban, Diagramma, ContoAllaRovescia, Notifica |
| Indicatori | Quadrante, Semaforo, Valutazione |
| Sviluppo | Terminale, EditorCodice |
| Didattica | Tutor, Assistente |
I controlli invisibili (Timer, DialogoFile, Appunti, Suono…) non hanno posizione: in Leo Studio stanno nella striscia sotto la finestra. I contenitori (Riquadro, Schede, PannelloScorrevole, Divisore, Scena) contengono altri controlli, e la posizione dei figli si misura dal contenitore.
Finestre che si allargano: gli ancoraggi#
I controlli si posizionano in pixel. Quando la finestra si ingrandisce, la proprietà ancoraggio decide che cosa fa ogni controllo: ancorato a sinistra e destra si allarga con lei; ancorato solo a destra si sposta; senza né sinistra né destra resta centrato. Lo stesso vale in verticale con alto e basso.
Esempio tipico: una casella di testo con ["alto", "sinistra", "destra"] si allarga; il pulsante OK con ["basso", "destra"] resta nell'angolo. In Leo Studio l'ancoraggio si imposta con un piccolo editor a quattro stanghette nel pannello Proprietà.