
La lezione introduttiva a Tkinter. Che cos'è e cosa ci si può fare. Presento anche qualche altra alternativa.
Per realizzare applicazioni a “finestra” servono delle librerie che si occupino della creazione delle parti grafiche (etichette, pulsanti, menu...) e dello scambio di informazioni con il sistema operativo (cosa che avviene con degli eventi). Esistono librerie di vario tipo che solitamente devono essere installate e mettono a disposizione dello sviluppatore un insieme di classi per la creazione delle applicazioni. Alcune librerie sfruttano le capacità e le caratteristiche del sistema su cui sono utilizzate (librerie native), altre invece offrono aspetti differenti, spesso maggiormente personalizzabili e di solito dall’aspetto più accattivante. Alcuni nomi di librerie molto utilizzate sono:
QT – librerie in C++ sviluppate nel 1991 da Trolltech. Semplificano lo sviluppo e presentano un aspetto moderno ed accattivante. Oggi usate per craere app per sistemi operativi classici ma anche nel mondo “mobile”. Possono essere utilizzate in Python con la libreria PyQT.
Tk – sono librerie Open Source già incluse in Python. L’aspetto è molto semplice ma si appoggiano sulle capacità del sistema operativo in cui sono utilizzate.
GTK – Librerie grafiche in C che si appoggiano sulle librerie native di Windows e di Linux.
Kivy – librerie di recente creazione create per Python. Permettono di creare interfacce
grafiche per dispositivi moderni e multi-touch.
L’argomento che stiamo per affrontare è molto vasto e per alcuni versi complesso. Ho cercato di selezionare degli argomenti fondamentali per apprenderne le logiche e poi procedere in autonomia (se l’argomento vi interessa).
Per poter seguire il corso dovete avere installato Python3 (https://www.python.org/downloads/) e un ambiente di sviluppo. Potete usare Thonny (https://thonny.org/) oppure PyCharm (https://www.jetbrains.com/pycharm/).
In questa lezione creiamo la nostra prima applicazione a finestre. Vedremo come lavorare con Thonny e con PyCharm.
Impariamo a utilizzare un pulsante e a collegare un semplice evento.
Utilizziamo un campo casella di testo per visualizzare nella finestra un saluto personalizzato.
Impariamo a conoscere ed utilizzare i Frame. Un Frame è semplicemente un rettangolo che può essere usato per disporre altri componenti al suo interno. Impariamo a creare gerarchie di componenti.
Il widget di tipo Frame realizza una cornice o meglio delinea un’area rettangolare in cui possiamo raccogliere altri widget.
Il Frame, come ogni altro widget deve essere associato a un altro Frame o alla finestra principale Tk. Il collegamento è indicato come primo parametro
app = tk.Tk()
fr = tk.Frame(app)
Possiamo indicare esplicitamente il legame utilizzando il parametro master. I due sistemi sono equivalenti.
app = tk.Tk()
fr = tk.Frame(master=app)
Per poterlo vedere dobbiamo associarlo alla finestra principale con pack() ma purtroppo se un frame non contiene nulla, non sarà visibile. Possiamo specificare per questo elemento delle proprietà ed indicare quali saranno le sue dimensioni.
Ancora esperimenti con i Frame e la composizione di gerarchie.
I Frame si possono utilizzare come raccoglitori di widget, per raggruppare i componenti ed ordinarli sulla finestra. Tkinter in realtà usa dei particolari metodi per disporre ed ordinare widget come il metodo pack() che affronteremo in dettaglio più avanti.
Quando creiamo un widget possiamo indicare a che elemento è collegato, definendo una gerarchia. L’elemento principale sarà sempre la finestra che istanziamo con Tk() e a questo possiamo “appendere” tutti gli altri. Possiamo creare un applicazione dimostrativa che ha due Frame collegati all’elemento principale, ogni frame con altri widget.
Sperimentiamo con il componente Label e alcune sue proprietà. Il widget Label serve per visualizzare testi e anche immagini.
Le proprietà principali di questo componente sono:
width, height –definiscono le sue dimensioni e sono espresse in pixel.
background – il colore dello sfondo indicato con un codice HTML o con il nome del colore
indicato come stringa e quindi ‘red’, ‘blue’....
foreground – è il colore del testo.
cursor - modifica l’aspetto del cursore quando scorre sopra all’elemento.
relief – modifica l’aspetto del riquadro che contiene il testo, creando un bordo oppure un
effetto rialzato o affossato. Le possibilità sono: flat, raised, sunken, solid, ridge o groove.
borderwidth – è la dimensione in pixel del bordo che appare attorno alla Label, nel caso il bordo sia previsto (es. con relief impostato a ridge potete variare la larghezza della
cornice).
Una proprietà particolare delle Label è la voce font con cui possiamo scegliere i caratteri grafici della scritta. I font utilizzabili sono quelli installati e disponibili nel vostro sistema operativo. Per modificare il font standard utilizzato dall’etichetta è necessario specificare la proprietà font indicando una tupla con il nome del font e la sua dimensione.
È possibile utilizzare una Label per visualizzare un’immagine. L’immagine deve essere in uno dei seguenti formati: GIF, PGM, PPM o PNG. Altri formati di immagine sono trattabili utilizzando specifiche librerie. Per il nostro esempio ho utilizzato una foto di Michael Sum presa dal sito unsplash.com (https://unsplash.com/photos/LEpfefQf4rU). Originariamente la foto era in formato jpeg, quindi l’ho convertita con un programma per la manipolazione grafica e l’ho ridotta alle dimensioni di 600x400. La foto è stata salvata in un cartella “imgs”. Per poter utilizzare l’immagine con una Label dobbiamo caricarla con l’oggetto PhotoImage:
photo = tk.PhotoImage(file='./imgs/cat.png')
In questo modo sarà utilizzabile da Label assegnandola direttamente alla sua proprietà image:
label['image'] = photo
https://unsplash.com/photos/LEpfefQf4rU (foto di Michael Sum su Unsplash)
I pulsanti sono oggetti cliccabili a cui possiamo associare delle azioni. Abbiamo visto nelle righe precedenti due modalità differenti per collegare il pulsante a delle funzioni che svolgeranno delle azioni. Possiamo modificare l’aspetto del componente utilizzando le sue proprietà:
· width, height –definiscono le sue dimensioni e sono espresse in pixel.
· background – il colore dello sfondo;
· foreground – per il colore del testo;
· font – per modificare il tipo di caratteri utilizzati;
· image – per associare un icona o un’immagine.
In aggiunta a queste proprietà segnalo anche state utile per disabilitare il pulsante quando non deve essere premuto.
bt['state'] = 'disabled'
I valori ammissibili per la proprietà state sono: disabled, active e normal.
Questo tipo di widget si utilizza per inserire del testo, infatti possiamo scrivere nel corpo della casella e poi utilizzare il testo immesso nella nostra applicazione. Anche per Entry valgono le proprietà comuni dei widget tra cui:
width, height –definiscono le sue dimensioni e sono espresse in pixel.
background – il colore dello sfondo;
foreground – per il colore del testo;
font – per modificare il tipo di caratteri utilizzati;
cursor - modifica l’aspetto del cursore quando scorre sopra all’elemento.
show – specifica il carattere da usare per visualizzare i caratteri. È utilizzato per
trasformare la casella di testo in un campo password.
I metodi principali per accedere al contenuto della casella di testo sono:
get() – restituisce il contenuto della casella di testo in una stringa.
delete(ini, end) – ripulisce i caratteri della casella di testo dalla posizione ini fino a end.
insert(posizione, stringa) – inserisce la stringa alla posizione indicata.
Possiamo accedere al testo immesso in una casella di testo in due modi. Il primo è quello di utilizzare i metodi get(), delete() e insert().
Esiste un secondo metodo per accede al contenuto di un campo di testo ed è quello che utilizza un oggetto particolare chiamato StringVar. Con questo approccio alternativo le operazioni risulteranno più chiare e semplici. L’oggetto StringVar offre un modello per la casella di testo ed evita di utilizzare gli indici per accedere al testo del widget. Per utilizzare una casella di testo con l’oggetto StringVar è necessario crearne un’istanza.
L’oggetto StringVar può essere utilizzato anche in modo “attivo” per tenere traccia delle modifiche che avvengono nel campo di testo a cui è associato e richiamare quindi una funzione associata.
In questa lezione utilizziamo anche un blocco try...except per catturare un'eccezione del codice.
Un altro componente molto importante nelle interfacce grafiche è il campo di testo che a differenza di una casella, dispone il testo su più righe. Questo widget è solitamente utilizzato Un altro componente molto importante nelle interfacce grafiche è il campo di testo che a differenza di una casella, dispone il testo su più righe. Questo widget è solitamente utilizzato
per realizzare editor perché permette di visualizzare anche numerose righe di testo. Come per gli altri elementi grafici del modulo tkinter espone una serie di proprietà per modificare il suo aspetto. Ecco le principali:
width, height –definiscono le sue dimensioni e sono espresse in pixel.
background – il colore dello sfondo;
foreground – per il colore del testo;
font – per modificare il tipo di caratteri utilizzati;
cursor – per specificare il tipo di cursore da utilizzare quando il componente è attivo.
state – per abilitare (‘normal’, ‘active’) o disabilitare (‘disabled’) il componente. I metodi principali per accedere al contenuto del campo di testo sono:
get(inizio, fine) – restituisce il contenuto compreso tra le due posizioni indicate.
delete(inizio, fine) – ripulisce i caratteri tra le due posizioni indicate.
insert(posizione, stringa) – inserisce una stringa nella posizione indicata.
L’utilizzo è un po’ particolare perché la get() e la delete() utilizzano una notazione particolare per indicare le posizioni. L’istruzione insert() inserisce una stringa alla posizione desiderata. Per l’inserimento si specifica un indice che va da 0 a END. Specificando END (una costante del modulo) il testo sarà aggiunto sempre in fondo a quello già presente
Le caselle di spunta (checkbutton) sono utilizzate di solito nei pannelli di configurazione delle applicazioni, quando si devono attivare delle opzioni. Questi widget possono essere associati a una variabile di tipo StringVar che assumerà due possibili valori. Le proprietà più comuni sono:
text – il testo da riportare di fianco alla casella.
width, height –definiscono le sue dimensioni in pixel.
background – per impostare il colore dello sfondo della casella;
foreground – per il colore del testo.
font – utilizzato per modificare il carattere utilizzato per il testo.
state – per abilitare (‘normal’, ‘active’) o disabilitare (‘disabled’) la casella.
Altre importanti proprietà per l’utilizzo delle checkbutton sono: command, variable, onvalue e offvalue.
L’ultimo tipo di componente che affronteremo è il RadioButton che assomiglia molto a una casella di spunta ma è di aspetto circolare. I radiobutton sono sempre raggruppati e permettono di scegliere una tra più voci disponibili ma in ogni istante uno solo degli elementi può essere ‘spuntato’. Per leggere il valore selezionato devono essere associati tutti ad una stessa variabile. Le proprietà più comuni sono simili a quelle degli altri widget:
text – il testo da riportare di fianco ad ogni voce.
width, height –definiscono le dimensioni dell’elemento, in pixel.
background – per impostare il colore dello sfondo dell’area del componente;
foreground – per il colore del testo di solito posto alla destra del pallino di spunta.
font – utilizzato per modificare il carattere utilizzato per il testo.
Link alla pagina con i widget: https://coderslegacy.com/python/list-of-tkinter-widgets/
Inviare messaggi all’utilizzatore delle nostre applicazioni è importante. A volte le informazioni sono riportate “sull’interfaccia”, cioè sui pannelli del programma e si possono leggere da caselle di testo, label e altri elementi. In alcuni casi dobbiamo richiamare l’attenzione dell’utilizzatore e richiedere un suo intervento o una sua risposta. Possiamo utilizzare delle finestre di tipo “dialog” (o modali) che appaiono di fronte a tutto e richiedono un intervento. Per questo motivo si dicono anche “bloccanti”. Esistono finestre dialog ti vario tipo: informative, di errore, di conferma, di avviso. A volte hanno un solo tasto per poterle chiudere, a volte chiedono una scelta tra due possibilità (e quindi hanno 2 pulsanti).
La creazione di una finestra modale non è per nulla complessa, infatti esiste un modulo di tkinter, chiamato messagebox che fornisce tre tipi di dialog pronte all’uso:
showinfo(title, message) – per messaggi informativi;
showerror(title, message) – per segnalare un errore;
showwarrning(title, message) – per riportare un avvertimento.
Per utilizzare queste finestre è necessario importarle dal sotto modulo messagebox, per esempio con:
from tkinter.messagebox import showinfo
Oppure ricordarsi, quando le utilizziamo di anteporre al loro nome messagebox: import tkinter as tk
tk.messagebox.showinfo('title', 'message')
I tre tipi di finestra richiedono due parametri:
il titolo che apparirà nella parte alta della finestra (se il vostro sistema operativo lo
prevede)
il messaggio da fornire all’utente.
Il testo dei pulsanti è preso dalla lingua impostata nel vostro sistema.
Fino ad ora non ci siamo per nulla preoccupati di come i vari componenti sono distribuiti sulla superficie occupata dalla nostra applicazione. L’unica cosa che abbiamo utilizzato è stato il misterioso metodo pack() che in qualche modo fa apparire i widget nella nostra applicazione ma senza capire molto cosa accada veramente. Disegnare un’interfaccia è molto complesso: non pensiate che sia sufficiente buttare in qualche ordine pulsanti e caselle di testo. Una disposizione accurata e ben pensata fa la differenza tra un’applicazione utilizzabile e una che irrita chi la utilizza. Il web e il mondo che ci circonda è pieno di applicativi malfatti o realizzati da persone che ignorino quanto sia importante la posizione di un pulsante su una interfaccia. Se volete approfondire l’argomento vi consiglio di leggere “La caffettiera del masochista” di Donald A. Norman e “Don’t make me think” di Steve Krug. Il primo libro vi insegna a creare oggetti pensati per chi li utilizza, mentre il secondo, un po’ datato ma ancora molto interessante ha un taglio più pratico presentando numerosi esempi per lo sviluppo web (e nella versione aggiornata anche mobile).
Perché è difficile disporre i componenti su un’applicazione a finestre? Perché la finestra può essere ridimensionata, oppure il programma potrebbe funzionare su diversi sistemi operativi e quindi l’aspetto potrebbe venir modificato.
La soluzione più semplice è quella di creare finestre a dimensione fissa e aggiungere i componenti in posti precisi, usando delle coordinate: nulla si muove e nulla si modifica. Purtroppo con la grande varietà di dispositivi e display, oggi nessuno si azzarda a utilizzare tale approccio. Si preferiscono dei layout fluidi o adattabili che garantiscono l’aspetto anche se le dimensioni cambiano. Utilizzare questi layout non è sempre semplice e soprattutto, oggi, si preferisce utilizzare dei programmi che si occupino del disegno delle interfacce lasciando a noi il compito di scrivere solo il codice per il suo funzionamento. Questi ambienti prendono il nome di RAD (Rapid Application Development) e hanno degli editor grafici dove si possono trascinare pulsanti, etichette e menu con grande facilità. Purtroppo per Tkinter non ci sono dei validi strumenti. Uno dei più utilizzati è Page (http://page.sourceforge.net/). Nonostante esistano tali strumenti, è importante sapere come funzionano i layout manager per poterli sfruttare al meglio. Tkinter prevede tre tipi di disposizioni:
l’impacchettamento (pack()),
la disposizione fissa,
le griglie.
Una finestra è di solito realizzata combinando anche più layout manager. SI può per esempio suddividere l’area in una griglia e poi all’interno delle celle utilizzare il pack() oppure una disposizione fissa, a seconda delle necessità.
Impacchettamento
Utilizzando il metodo pack() aggiungiamo widget a una finestra o a un Frame. Il modo in cui il componente è aggiunto e poi visualizzato è deciso dall’algoritmo di impacchettamento che:
calcola l’area necessaria (definita parcel) per il widget aggiungendo anche dello spazio
vuoto per il riempimento;
centra il componente nello spazio calcolato.
Proviamo a impostare una finestra utilizzando i frame e pack() per suddividere lo spazio e poi disporre i componenti. Quando si realizza un’applicazione è sempre bene provare a disegnare su un foglio l’aspetto che dovrebbe avere e ragionare sulle varie funzionalità, insomma, prima di passare al codice si devono avere le idee ben chiare. Immaginiamo che ci serva un programma con i componenti organizzati su due righe.
Per disporre i componenti in un’applicazione tkinter possiamo utilizzare un posizionamento assoluto, cioè specificando in modo preciso le coordinate degli elementi da aggiungere. Come abbiamo detto questo metodo è intuitivo per un principiante ma l’interfaccia non si adatterà alle dimensioni della finestra. Tenete presente che se una Label deve visualizzare un testo e ha delle dimensioni impostate, con questo sistema risulterà “tagliata” e il testo illeggibile. Con un sistema dinamico, allargando la finestra la Label riceverà più spazio e riuscirete a leggere il suo contenuto. Un altro inconveniente è dato dalla difficoltà che si incontra nella gestione di interfacce complicate: più widget sono presenti e più calcoli e controlli dovremo fare.
Per posizionare un elemento sulla finestra useremo il metodo place(x, y). I due parametri sono le coordinate in cui posizionare l’elemento. Fate attenzione che l’origine delle coordinate è posta nell’angolo superiore sinistro della finestra, la x cresce verso destra mentre la y verso il basso!|
L’ultimo metodo per disporre i componenti su una finestra Tk è quello di utilizzare una griglia. Questo layout manager permette di ottenere delle disposizioni anche complesse e che si possono adattare alle dimensioni della finestra. Per disporre i componenti su una griglia utilizzeremo il metodo grid() indicando la colonna e la riga in cui inserire il componente. Il numero totale di righe e colonne non è dichiarato da nessuna parte ma è calcolato di volta in volta mentre aggiungiamo componenti. Passando alcuni parametri a grid() possiamo modificare l’aspetto delle celle.
Proviamo a impostare una semplice tastiera numerica per una calcolatrice. Utilizzeremo la disposizione su una griglia. Per aiutarsi nella disposizione dei pulsanti possiamo tracciare un disegno oppure un foglio di calcolo come Excel o Calc che ci servirà solo per capire come organizzare la schermata.
Ogni interazione con un’applicazione “visuale” genera degli eventi. È importante capire che tipo di eventi possono essere generati e come trattarli. In un moderno sistema operativo le interazioni con i programmi a finestra avvengono principalmente con il mouse, cliccando o trascinando gli elementi presenti. Altri eventi possono provenire dalla tastiera che utilizziamo per intraprendere azioni alternative a quelle possibili con il mouse. A volte il clic del mouse è integrato dalla pressione di tasti singoli o combinazioni per moltiplicare le possibilità di azione. A volte la tastiera può essere utilizzata in alternativa al mouse. Altri eventi ancora possono provenire dal sistema operativo che ha necessità di comunicare qualche cosa alla finestra in esecuzione.
Abbiamo visto come sia possibile collegare un azione a un pulsante in due differenti modi, utilizzando il parametro command e specificando il nome di una funzione da richiamare o con il metodo bind(). Negli esempi precedenti abbiamo prediletto l’uso di command che per la maggior parte dei casi è rapido e semplice. Con command leghiamo il clic con il tasto sinistro (l’azione più comune ) a una funzione che eseguirà del codice.
L’utilizzo di bind() ci permette di utilizzare un maggior numero di tipologie di eventi e di rendere esplicito il “legame” (bind) tra l’azione e la conseguenza.
Quando utilizziamo degli aventi abbiamo sempre tre elementi:
l’evento a cui siamo interessati o che vogliamo catturare,
una funzione detta “gestore dell’evento” (event handler) con il codice da eseguire in seguito all’evento,
il collegamento tra l’evento e la funzione (legame o bind).
Gli eventi che possiamo intercettare sono numerosi e possiamo attivarli utilizzando delle semplici stringhe.
Gli event handler utilizzati fino ad ora non prevedono parametri aggiuntivi oltre ad event. Potrebbe capitare di voler aggiungere delle informazioni in più per il nostro event handler. Possiamo riuscirci utilizzando una scrittura particolare che richiede la creazione di una “lambda function” cosa che potremmo semplicisticamente definire come una specie di funzione definita “al volo”. Con la scrittura:
lambda x: x + 1
creiamo una funzione che riceve un parametro x e restituisce il valore incrementato di 1. I parametri di questo tipo di funzioni sono posti prima dei due punti, mentre il codice è alla loro destra. Questo codice non è richiamabile se non lo associamo a un qualche tipo di riferimento. Scriviamo allora:
add1 = lambda x: x + 1
Ora abbiamo collegato il codice della funzione al nome add1 che si potrà usare come una funzione. Chiamando:
n = add1(2)
print(n)
Nella console vedremo apparire il numero 3. Applichiamolo a una applicazione Tk a cui abbiamo aggiunto un pulsante che richiamerà una funzione chiamata funConParametri(): bt = tk.Button(app, command=funConParametri)
Definiamo la funzione in questo modo, così che riceva tre parametri a, b e c: def funConParametri(a, b, c):
print(a, b, c)
Possiamo chiamare funConParametri() definendo al volo una lambda funzione che la richiami e che abbia i valori dei parametri già prefissati.
bt = tk.Button(app, command = lambda a=1, b=2, c=3: funConParametri(a, b, c))
Ora premendo il pulsante, richiameremo funConParametri() con i tre parametri impostati.
Possiamo collegare degli event handler anche alla finestra principale delle nostre applicazioni, l’oggetto Tk. Solitamente collegheremo eventi provenienti dalla tastiera utilizzando sempre il metodo bind():
app = tk.Tk()
app.bind("<Key>", getTasto)
Mettendoci in ascolto dell’evento <Key> riceveremo tutti gli eventi provenienti dalla tastiera e potremo selezionare quelli che ci interessano.
Quando non si è più interessati ad un evento, possiamo disattivare il binding con: bt.unbind('<Button-1>')
Ecco alcuni possibili codici/nomi per i tasti:
<Alt>
<Control>
<Shift>
<Alt_L>
<Alt_R>
<BackSpace>
<Cancel>
<Caps_Lock>
<Control_L>
<Control_R>
<Delete>
<End>
<Escape>
<F1>
<Home>
<Insert>
<Return>
<Right>, <Left>, <Up>, <Down>
<Tab> tasto tabulazione
Qui di seguito una lista di eventi scatenati in seguito a varie condizioni:
<Activate> un widget si attiva
<Button-1>, <Button-2>, <Button-3> pressione di uno dei tasti del mouse
<ButtonRelease-> tasto rilasciato
<Deactivate> un widget si disattiva.
<Enter> Il puntatore del entra nell’area del widget
<Leave> il puntatore del mouse esce dal widget
<Motion> il puntatore si muove
Tutti gli oggetti, i widget, le finestre di tkinter sono degli oggetti. Possiamo creare delle applicazioni migliori sfruttando queste caratteristiche. Anche se il codice che scriveremo sembrerà un po’ più complesso del solito, l’approccio ad oggetti fornirà le basi per un architettura più ordinata ed estendibile, inoltre potremo separare l’aspetto di un’applicazione con la parte funzionale. Questa tecnica molto usata dai programmatori è utile per organizzare meglio il software dividendo:
- I dati o i modelli delle informazioni
- Il codice che si occupa di visualizzare i dati, delle interfacce, delle interazioni con
l’utilizzatore
- Il codice che elabora i dati.
Questo approccio è anche definito MVC, cioè Model View Control.
La classe Tk che abbiamo sempre usato come punto di partenza e che ci offre la finestra principale, può essere estesa per creare la mostra applicazione.
Possiamo estendere non solo la classe Tk ma ogni altra classe delle librerie tkinter. Se abbiamo necessità di un componente con particolari caratteristiche possiamo estenderne uno da utilizzare come punto di partenza e personalizzarlo secondo le nostre necessità. Le applicazioni reali utilizzano spesso più pannelli che possiamo visualizzare o attivare a seconda delle necessità, per questo è prassi comune creare delle classi personalizzate partendo dai Frame.
Molte applicazioni richiedono vari pannelli che possono comportarsi come “pagine” da visualizzare a seconda delle funzioni o dei dati. Molti programmi hanno una schermata operativa e magari un pannello di configurazione. Come possiamo organizzare un comportamento del genere utilizzando più Frame? Il sistema è in realtà abbastanza semplice: aggiungeremo i pannelli uno sopra l’altro portando quello che ci interessa in primo piano.
Le applicazioni grafiche spesso devono effettuare delle operazioni che richiedono parecchio tempo, solitamente quando accedono a risorse in Rete, utilizzano dell’hardware come le porte seriali, dipendono da altri eventi esterni o devono effettuare delle lunghe elaborazioni. In questi casi, se il codice non è ben scritto, la finestra principale si “congelerà” ed ignorerà ogni interazione (si dice che diventa irresponsiva – maltradotto dall’inglese “irresponsive”). Per evitare questi blocchi dobbiamo utilizzare dei Thread che possano prendersi carico di questo tipo di elaborazioni in sottofondo (background). Immaginiamo di voler creare una semplice applicazione che avvia un conteggio alla pressione di un tasto e che aggiorna una Label.
Realizziamo un convertitore di misure utilizzando un App e le librerie Tkinter. Prima di tutto tracciamo l’aspetto dell’applicazione utilizzando carta e penna oppure un foglio di calcolo. L’applicazione avrà un semplice pannello su cui disporremo:
un titolo
una casella di testo in cui inserire la misura in pollici
una casella di testo per la misura in centimetri
un pulsante per trasformare i pollici in centimetri
un pulsante per trasformare i centimetri in pollici
Potremo inserire un numero in una delle due caselle e premendo i pulsanti attiveremo la conversione.
Realizziamo un editor di testi utilizzando il componente Text e le classi tkinter. L’interfaccia del programma sarà molto semplice perché tutto lo spazio sarà destinato all’editor mentre le azioni saranno raccolte in un menù. Il programma potrà quindi aprire un file di testo e visualizzare il contenuto, potremo modificarlo e salvarlo su disco.
Realizziamo un altro classico programma per computer: un applicazione per disegnare con il mouse. La particolarità di questo programma è che all’apertura mostreremo uno splash screen, cioè una schermata con un logo o il nome dell’applicazione che sparirà non appena il programma sarà pronto per l’utilizzo. Anche questa è una caratteristica che troviamo in molti software commerciali e possiamo sfruttare per creare dei programmi che siano piacevoli da usare.
Conclusione del corso.
Ti ringrazio per aver seguito e acquistato il mio corso. Spero ti sia stato utile.
Ciao,
Paolo Aliverti.
In questo corso imparerai a realizzare interfacce grafiche GUI in Python con Tkinter. Con Tkinter è possibile realizzare applicazioni multipiattaforma per Windows, Linux o MacOS con semplicità. Potrai "vestire" i tuoi programmi dandogli un aspetto più accattivante e professionale. Le applicazioni GUI facilitano le interazioni degli utenti con il sistema operativo e oggi sono la norma. In questo corso impareremo come creare applicazioni a finestre, aggiungendo componenti, menu, dialog e sviluppando semplici programmi.
Le lezioni prevedono sempre una piccola parte teorica seguita da esempi pratici ed esercizi. Affronteremo vari temi come l'utilizzo dei componenti, le interazioni e gli eventi, l'apertura di finestre secondarie e dialog modali, la disposizione degli elementi sulle interfacce. L’argomento che stiamo per affrontare è molto vasto e per alcuni versi complesso. Ho cercato di selezionare degli argomenti fondamentali per apprenderne le logiche e poi procedere in autonomia (se l’argomento vi interessa).
Per poter seguire il corso è richiesta una conoscenza di Python e della programmazione a oggetti (OOP).
Io mi occupo professionalmente di programmazione dal 2000. Ho lavorato presso varie multinazionali ricoprendo il ruolo di programmatore, analista, project manager. Utilizzo vari linguaggi di programmazione tra cui C/C++, Java, Python, Swift e linguaggi per il web. Mi occupo anche di sviluppo di prototipi elettronici e programmazione di firmware.