Quanti di voi hanno studiato svariati linguaggi di programmazione senza creare poi qualcosa di effetto? E quanti hanno a lungo sperato di poter scrivere un programma dalla a alla z? Io sono tra queste persone e in questa guida cercherò di analizzare tutti gli aspetti fondamentali legati alla creazione di un programma con interfaccia grafica in Python partendo da zero.
Perché Python?
Python è un linguaggio di alto livello, orientato ad oggetti, davvero valido per la sua versatilità e compatibilità in quanto linguaggio interpretato e non compilato; questo comporta che un programma scritto in Python viene compilato, di volta in volta, sul computer su cui viene eseguito e quindi chiaramente non sorgono problemi di compatibilità (per questo lo consiglio vivamente a chi si affaccia per la prima volta al mondo della programmazione software). L’unico limite è il fatto che spesso è necessario importare un determinato modulo che risulta praticamente impossibile da trovare o che manifesta problemi di compatibilità con la versione di Python installata. Per iniziare è necessario scaricare l’ambiente di sviluppo del programma ovvero l’IDE di Python 2.7; questo basta di per sé per creare un programma base (eseguibile in shell) tuttavia noi vogliamo creare un programma con interfaccia grafica quindi bisogna installare il pacchetto di implementazione Wx_Python (dato che ci occupiamo delle implementazioni è utile, per il futuro, installare anche PyOpenGL e NumPy).
Le basi
Prima di vedere le funzionalità del modulo grafico wx è necessario apprendere le basi del linguaggio; a tale scopo le riassumo molto brevemente (tuttavia se è la prima volta che programmate vi consiglio di leggere qualche guida più dettagliata). Le variabili, in Python, non vanno dichiarate, assumono una tipologia in base al tipo di dato che gli viene assegnato la prima volta. L’istruzione print permette di stampare a video una stringa, un numero o il contenuto di una variabile mentre le istruzioni di input permettono di "leggere" un input esterno (si usa raw_input per le stringhe). I commenti vanno scritti dopo il simbolo # e va rispettata con rigore l’indentazione. La selezione if ha la seguente sintassi:
if x>0: #se la condizione x>0 è vera allora print 'x è maggiore di 0' else: #altrimenti print 'x minore o uguale a 0'
È possibile eseguire cicli if annidati tramite l'istruzione elif al posto di else if Il ciclo while ha la seguente sintassi:
while x>0: #condizione print 'x è ancora maggiore di 0' #effetto x-=1 #ogni volta che esegue il ciclo x diminuisce di 1
Il ciclo for:
for x in range(10): #intervallo print x,'è il ', x+1, '° numero' #effetto
Gli array sono particolari variabili in cui è possibile inserire più di un valore; per indicare la localizzazione di un valore si usa la notazione nome_array[n] (che equivale al valore assegnato all’array nel suo ‘spazio n-1’). Essendo Python un linguaggio di oop (Programmazione Orientata da Oggetti) è essenziale introdurre i concetti di funzione, classe e modulo. La classe è un insieme di funzioni all’interno di un modulo; le funzioni sono "pezzi di codice" che possono essere richiamati in qualunque momento e anche più volte mentre una classe è un insieme di più funzioni ed infine un modulo è un file che generalmente comprende una o più classi (per importare un modulo si usa import nome_modulo).
Scriviamo il programma
In qualità di ciclista voglio creare un semplice programma che raccolga i dati delle mie escursioni e che mi faccia vedere i grafici, la mappa e le foto dei miei giri. Creiamo un file .py e lo salviamo in una cartella a nostro piacimento ove andremo a creare un sistema di sottocartelle che conterrà l’interprete di Python e i contenuti multimediali del programma. Tramite l’IDE di Python andiamo a scrivere le prime righe:
#-*- coding: iso8859_2 -*- #serve per la codificazione di caratteri speciali import wx #importo il modulo wx class MyFrame(wx.Frame): #creo la classe MyFrame che andrà a contenere il codice def __init__(self, *a, **k): #creo una funzione wx.Frame.__init__(self, *a, **k) global B_escursioni, font5, font1,font2, con, bitmap1, fcon #definisco le variabili globali (altrimenti non le posso utilizzare fuori dalla funzione) self.CreateStatusBar() #creo una status-bar self.SetStatusText(" Mountain Bike Progress Recorder ") ico = wx.Icon('resources/images/icone\ico.ico', wx.BITMAP_TYPE_ICO) self.SetIcon(ico) #assegno come icona il file ico.ico image_file = 'resources/images/sfondo.jpg' #indirizzo dell’immagine di sfondo bmp1 = wx.Image(image_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap() #la converto in #bitmap self.bitmap1 = wx.StaticBitmap(self, -1, bmp1, (0, 0)) #creo una bitmap statica #figlia del Frame stesso tramite l'istruzione self self.SetTitle('Mountain Bike Progress Recorder') #assegno il titolo app = wx.App(False) frame = MyFrame(None, style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE) frame.Show() app.MainLoop()
Le ultime quattro righe di codice sono essenziali in quanto servono per impartire al programma l’ordine di mostrare il frame (la finestra principale) e mandarlo in main_loop.
Architettura di un programma
È fondamentale conoscere l’architettura dei programmi per poterne creare uno. Un programma è costituito da un Frame ovvero la ‘finestra principale’ al cui interno sono collocati i vari widget ovvero gli oggetti del programma. Al Frame vengono affiliati i panel ovvero invisibili pannelli che "rivestono lo spazio interno del frame" e i vari widget (come bottoni, bitmap, radiobutton e check box, input box, static text, etc.). Per il parent, quando creo un oggetto grafico tramite il modulo wx devo scrivere:
nome_oggetto=wx.tipo_oggetto(self, -1, size=” ”, pos=” ”)
dove self indica che l’oggetto è "figlio" del Frame (posso anche dichiarare che esso sia figlio di un panel o di una bitmap), -1 indica la creazione automatica dell'id del widget, size e pos che mi indicano le dimensioni e la posizione in pixel dell’oggetto. I dialogue sono, invece, finestre grezze create allo scopo di inserire dati e informazioni.
Le istruzioni più utili
Per creare un bottone uso l’istruzione:
Font1 = wx.Font(pointSize = 18, family = wx.DEFAULT, style = wx.NORMAL, weight = wx.NORMAL, faceName = 'Consolas') #creo un font per le scritte del bottone Nome_bottone=wx.Button(self.bitmap1,-1,'Lista Escursioni',pos=(30,30),size=(30,50) #creo il bottone vero e proprio, lo descrivo come ‘figlio’ di self.bitmap1 ovvero #della bitmap dello sfondo (denominata bitmap1) che a sua volta è figlia del Frame B_escursioni.Bind(wx.EVT_BUTTON, self.on_B_escursioni) #l’istruzione EVT_Button stà per event button ovvero l’evento collegato al bottone; #in questo caso quando clicco sul bottone esegue la funzione on_B_escursioni B_escursioni.SetFont(font1)
Per creare un panel:
nome_panel=wx.Panel(self, -1, pos=(0,0), size=(1368,690)) nome_panel.SetBackgroundColour((255, 255, 255)) #serve ad indicare il colore di sfondo
Per distruggere un widget (o un oggetto in generale):
nome_oggetto.Destroy()
Attenzione perché quando distruggo un oggetto tutti gli oggetti figli di quest'ultimo vengono distrutti automaticamente. Per creare una funzione:
def nome_funzione(self, evt): global nomi_variabili_globali
Nella parentesi vanno inserite le variabili da passare alla funzione tuttavia se la funzione è collegata ad un bottone bisogna inserire self e evt (che corrisponde a event). Per creare una bitmap statica:
bitmap = wx.Bitmap('resources/foto/001.bmp', wx.BITMAP_TYPE_BMP) nome_bitmap = wx.StaticBitmap(nome_panel, -1, bitmap, pos=(0,0), size=(10,10))
Per creare un testo statico:
nome_testo = wx.StaticText(nome_panel, -1, label='Ciao', pos=(0,0)) nome_testo.SetFont(nome_font) nome_testo.SetBackgroundColour((255,255,255))
Per creare una barra dei menù:
self.menubar = wx.MenuBar() self.fileMenu = wx.Menu() nome_opzione_1 = self.fileMenu.Append(-1, _("Save model")) self.Bind(wx.EVT_MENU, ...) self.fileMenu.AppendSeparator() nome_opzione_2 = self.fileMenu.Append(-1, _("Load file")) self.Bind(wx.EVT_MENU, ...)
Per creare un dialog di caricamento file (in questo caso potrò caricare .stl, .gcode o .txt):
nome_dialog = wx.FileDialog(None, "Load a file", ".", " ", "STereo Lithography file (*.stl)|*.stl|Gcode file (*.gcode)|*.gcode|Text file (*.txt)|*.txt|All files|*.*", wx.OPEN) if nome_dialog.ShowModal() == wx.ID_OK: wx.MessageBox("The name of the file is: " + dlg.GetFilename() + "\nThe file path is: " + dlg.GetPath())
Per convertire un numero in stringa:
str("%2.0f" % numero)
Il numero 2.0 indica che il numero può avere due cifre prima della virgola e nessuna dopo; inoltre se inserisco un numero con un numero di cifre, prima della virgola, minore da quello indicato, il programma lo convertirà in una stringa con tanti spazi quanto vale la differenza di cifre. Per convertire una stringa in numero:
int(nome_stringa) #oppure float(nome_striga)
In conclusione, per quanto modesta possa essere questa guida, vi ho descritto i comandi base (e quindi i più utili) per creare un programma con python ora sta a voi stupirvi delle potenzialità di questo linguaggio.
Edoardo Lenzi
Ma quindi aprite una serie su python? Bene! La mia richiesta è stata accettata :)))
Che prevede il programma?
Buongiorno Antonello,
In realtà non era mia intenzione iniziare una serie di articoli su python ma dato il tuo interesse forse si potrebbe pensare di farne una. Avresti qualche proposta? Qualcosa che ti incuriosisce particolarmente? Grazie.
Edoardo
In verità anche a me interessa Python e mi piacerebbe un corso per programmare con esempi pratici e progetti da sviluppare.
Non conosco tutte le reali potenzialità quindi vorrei sapere a cosa può servire programmare in python, in termini di applicazioni, e poi vedere qualcosa di simile al corso di android o a quello di microprogrammazione. insomma, qualcosa alla eos. 🙂
Grazie per aver preso in considerazione la cosa.
Anche a me interessa! 😀
Anche a me. Vorrei appunto trasferire tutta la logica di un programma in bash Shell scripts, basato su linea di comando, niente interfaccia grafica, ad una con tutti gli oggetti tipici di un’interfaccia grafica.
Buongiorno Antonello,
interessante l’articolo, ma come mai la scelta di wxPython e non di altri tipi di librerie grafiche come ad esempio PyQT/PySide o PyGTK?
Per le PyQT c’è QT designer che non è male… Per creare la GUI invece cosa usi con WX_Python?
Grazie
Roberto
Buongiorno a tutti.
Un editor visuale per wxPython è wxFormBuilder.
Si disegna l’interfaccia e poi si produce il codice in un file .py.
Il QtDesigner per esperienza so che produce il codice dell’interfaccia in C++. Non so se produce direttamente codice python.
PyGTK è molto simile a PyQT come filosofia, esiste Glade che permette di disegnare l’interfaccia, ma non credo ci sia il generatore di codice Python.
Avere il codice python pronto all’uso (come wxPython) svincola da doversi preoccupare di caricare i vari componenti dell’interfaccia.
scusate… la mia domanda era per Edoardo Lenzi non per Antonello..
Buonasera Roberto e grazie per il commento,
in realtà non c’è una grande differenza tra le librerie grafiche che hai nominato, sono tutte molto valide e, tralasciando i formalismi, equivalenti.
La scelta delle wxPython anziché le PyQt deriva principalmente dal fatto che siamo su Elettronica Open Source e, mente le Qt sono un progetto commerciale gestito da Nokia,
le wx sono un progetto interamente Open Source.
Per ognuna delle tre librerie esistono delle implementazioni che ‘cercano’ di essere RAD (per wxPython c’è Boa Constructor) tuttavia ti sconsiglio vivamente di utilizzarle in quanto è vero che sono sicuramente più immediate che lavorare solo con il codice ma hanno un enorme problema legato al codice generato che è ridondante e quindi di basso livello (tolto il fatto che sarai limitato dalle poche opzioni); questo fatto rallenta l’interpretazione del codice e di conseguenza il programma stesso.
Edoardo
Salve,
per quel che ne so (ho usato Qt, TKinter e wxWidget) mi sembra che le differenze tra i toolkit (oltre la diversa architettura) esistono, basta guardare ad es. alla gestione degli eventi. E’ vero che sono tutte valide, comunque.
Inoltre PySide è l’implementazione open source delle Qt per Python, il progetto è nato proprio per questo scopo. http://en.wikipedia.org/wiki/PySide.
Buongiorno mscafoglieri,
togliamo TKinter a cui sono molto affezionato ma è doveroso dire che ormai è un modulo superato; mi dispiace per la mia inesattezza ma non ho mai usato PySide tuttavia credo che, tralasciando i formalismi, il concetto di base sia il medesimo (anche per quanto riguarda gli eventi), confermi?
Quello che voglio dire, forse un po’ troppo generalizzando, è che librerie grafiche differenti avranno architetture affini ma leggermente diverse, in base al metodo di chi le ha sviluppate, tuttavia una volta appreso il concetto di base non si avrà alcuna difficoltà a passare dall’una all’altra.
Edoardo
Edoardo,
TKinter non l’ho aggiunto, l’ho solo usato e uso ancora con soddisfazione, come te, credo.
Per il resto, mi spiace, ma non sono d’accordo, anche perchè non mi risulta esista un “concetto di base” per i GUI toolkit.
Sia chiaro, il mio vuole essere un parere (spero costruttivo) su un’affermazione che a me è risultata non vera, non un commento negativo all’articolo che, anzi, credo sia ben fatto.
Anche io sono piuttosto convinto che i vari framework abbiano differenze a volte importanti che non rendono proprio immediato passare con disinvoltura da uno all’altro.
Inoltre c’è da considerare che le qt (ad esempio) vanno ben oltre le semplici funzionalità di gestione della grafica, di finestre e widget. Infatti implementano classi per la gestione della seriale, per la gestione di comunicazione interprocess, thread ecc.
Segalo nfine, a complicare ulteriormente il panorama, un framework un po’ diverso, reso imo interessante dal suo linguaggio dichiarativa (un po’ sulla stessa idea di QML). Si chiama kivy e si trovano in rete diversi tutorial. Per fare cose veloci per me e
dodo, sentiamoci 🙂
Mi pare chiaro che ci sia da fare un programma 🙂
Wow non credevo fosse un argomento così interessante, avrei dovuto proporlo agli Oscar!
Farò un altro articolo di sicuro e forse anche più di uno però badate bene che non sono un programmatore, ne ho mai studiato programmazione (se non per conto mio).
Tuttavia è un po’ troppo comodo trovare “la pappa pronta” così vorrei che tutti contribuissero a darmi una mano scrivendo le loro idee nel forum che aprirò. Sono ben accetti aiuti da parte di coloro che conoscono bene particolari moduli di Python (in particolare Open_GL) per i prossimi articoli.
Edoardo
Sperando di fare cosa gradita, mi permetto di segnalare un’ottima guida per la programmazione grafica in Python con PyQt disponibile gratuitamente online:
“Rapid GUI Programming with Python and Qt” è corredata anche dei file sorgenti degli esempi del codice trattato per varie piattaforme (Linux/Windows/Mac).
Questo libro è su PyQT ma se si usa PySide la differenza è minima.
Colgo l’occasione per chiedere ad Edoardo Lenzi se renderebbe disponibile anche il codice sorgente dell’applicazione.
Grazie
Scusate ero convinto di avervi messo il source code.
download: https://www.dropbox.com/s/by5ktpz1cbq3i6c/MTB.zip?dl=0
Grazie 🙂
Grazie per la guida! 🙂
Una domanda.. funziona con py3?
Si, dovrebbe esserci per py3.x http://stackoverflow.com/questions/720806/wxpython-for-python-3
Interessante articolo. Anche a me interesserebbero una serie di articoli su Python.
Una panoramica delle degli ambiti di utiizzo. In particolare su LibreOffice o per ARDUINO (o Raspberry Pi)
Mi associo alla richiesta. Vorrei imparare a programmare in Python, potreste consigliarm iuna guida che parta dalle basi ( possibilmente in ITA )
Grazie
Buongiorno a tutti, sono un amante del free software e, oltre a collaborare con qualche progetto open source mi appassiona la programmazione. Python potrebbe essere molto interessante vista la sua natura alto livello e multipiattaforma ma vorrei sapere se fosse possibile creare una gui per un comando bash o cmq, un software con interfaccia grafica Gtk+ o Qt da usare su più sistemi. E in caso di porting su win e osx, ad esempio, occorre installare anche le librerie qt e/o Gtk. Grazie
Si, è possibile fare quello che chiedi in particolare con Qt. Per quanto riguarda l’installazione, usando pyinstaller o software similari viene generato direttamente un file eseguibile sulla piattaforma di riferimento senza poi necessità di installare librerie o altro.
Ciao
Quoto quanto gia’ scritto da mscafoglieri; in passato feci una GUI via QT + Python e fu abbastanza semplice, anche se ti puoi scordare (almento per quel che ne so) strumenti molto integrati (RAD).
In pratica io generavo i files della gui con QtDesigner che poi venivano processati da un tool (delle pyQt) che ne permetteva poi l’utilizzo con python…. comunque piu’ facile a farsi che a dirsi 🙂
Aggiungo inoltre, se il tuo obiettivo e’ fare piccole GUI per script bash che non necessitano di interfacce particolarmente evolute, che puoi usare le librerie ncurses.
Ovviamente il risultato (visivo e interattivo) e’ molto differente ma hai il vantaggio di poter usare tali GUI anche su sistemi privi della parte grafica, anche via ssh.
Questo pero’ non so quanto sia portabile sotto Windows…. non ho esperienze a riguardo
Articolo davvero interessante per chi, come me, é sempre stato incuriosito dalla programmazione Pyton da quando ho collaborato con un mio docente come tester per una tastiera sillabica…
Volendo approcciarmi a questo tipo di programmazione, cosa mi consigliereste di fare? Che compilatore usare? Un buon manuale? Mi rivolgo ovviamente all’autore, ma ovviamente accetteró consigli da chiunque voglia darmene =)
Ciao Fabrizio,
grazie per il tuo commento. Dipende essenzialmente dal tuo background e da cosa hai in mente di fare; in primo luogo se hai già scritto dei programmi in qualche altro linguaggio di programmazione conosci già le basi e ti basta andare nella sezione Documentazione del sul sito ufficiale di Python (dove trovi guide, tutorial e tutte le informazioni di cui hai bisogno). Se invece parti proprio da zero e vuoi un video-tutorial in italiano ti consiglio di guardare i video di NiktorTheNat su YouTube oppure “Tutorial per principianti in Python” di Josh Cogliati.
Può anche essere che Python non sia il linguaggio più indicato per i tuoi progetti, magari andresti meglio con C-C++. Edoardo
Grazie della risposta Edoardo,
diciamo che ho esperienze di programmazione in C++… Secondo te Python per cos’é particolarmente indicato a livello di utilizzo? Nel senso, per cosa lo preferiresti al C++? Grazie anticipatamente =)
Ciao!
Prima di tutto il Python è interpretato.
E’ comunque molto veloce, e potente.
Con il C e o C++ puoi fare tutto, ma è tutto da costruire, oppure utilizzare librerie già scritte che comunque bisogna studiare bene prima di poterle inserire nei nostri programmi.
Come ti ha già detto Edoardo tutto dipende da cosa preferisci e soprattutto, se hai un obbiettivo vicino e preciso o se lo vuoi studiare per una tua crescita di conoscenze in quel caso di consiglio di prendere il toro per le corna ed impararti il C.
Se impari bene quello non ti ferma più nessuno.
Sergio
Grazie della risposta Sergio! =)
Ho conoscenze di C a livello universitario (studiavo sul Kernighan & Ritchie), quindi dovrei rinfrescarmi un attimo le conoscenze…
Quello che mi é parso di capire é che il Python sia un pelo piú immediato da imparare rispetto al C, che io ho personalmente sempre definito piuttosto ostico (specie per quanto riguarda i puntatori).
Anch’io sono molto contento se verrà fatta una serie su python. Mi ha sempre incuriosito visto che pare sia più veloce e duttile rispetto ad altri linguaggi.
Stefano
Buongiorno,
È un articolo molto interessante per chi vuole incominciare e la cosa può essermi utile.
Mi chiedevo se con python si potesse creare un programma gui che potesse gestire delle periferiche con Raspberry e, perché no, anche Arduino tramite Raspberry con connessione seriale o I2C.
Buongiorno. ottimo articolo davvero, peccato che su linux wx non funzioni così tanto bene.. ci ho messo un bel po’ prima di trovare nei repo le librerie (online si trovavano solo versioni troppo vecchie) e una volta fatto tutto nemmeno il vostro script in python funziona, riportando da terminale che è stato creato un dump.
Copiandolo da questa pagina il risultato sono errori ogni singola riga..
La serie su python sarebbe assai interessante perchè una guida semplice su come programmare e fare interfacce grafiche è cosa molto bella e su internet non sempre tutto è molto chiaro..
Complimenti ancora!