Creare un programma con interfaccia grafica in Python (partendo da zero).

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

33 Commenti

  1. Antonello Antonello 6 novembre 2014
  2. dodo dodo 6 novembre 2014
    • Boris L. 7 novembre 2014
    • Mauro Bodale Casula Mauro Bodale Casula 21 marzo 2016
    • Roberto Renna 1 novembre 2016
  3. doppio7 6 novembre 2014
    • mauroziliani 31 ottobre 2016
  4. doppio7 6 novembre 2014
    • dodo dodo 6 novembre 2014
      • mscafoglieri 7 novembre 2014
        • dodo dodo 7 novembre 2014
          • mscafoglieri 7 novembre 2014
          • Ivan.Tarozzi 21 novembre 2014
  5. Piero Boccadoro 7 novembre 2014
    • dodo dodo 7 novembre 2014
  6. doppio7 7 novembre 2014
  7. dodo dodo 7 novembre 2014
  8. AntonioBlescia AntonioBlescia 10 novembre 2014
  9. Marco.Ce 16 dicembre 2014
  10. citrix 1 gennaio 2015
  11. Davide Cusano 5 gennaio 2015
    • mscafoglieri 5 gennaio 2015
    • Ivan.Tarozzi 5 gennaio 2015
  12. Fabrizio Bianchini 21 gennaio 2015
    • dodo dodo 21 gennaio 2015
      • Fabrizio Bianchini 21 gennaio 2015
        • sergio_arduino48 sergio_arduino48 21 gennaio 2015
          • Fabrizio Bianchini 21 gennaio 2015
  13. stefanop stefanop 22 gennaio 2015
  14. Francesco Cornalba Francesco Cornalba 17 febbraio 2016
  15. Alessio Bevilacqua 1 novembre 2016

Scrivi un commento