GUI

17 marzo 2006

Nota: lezione in aggiornamento

In questo articolo vediamo come utilizzare Python anche per costruire applicazioni con interfaccia grafica a finestre, menu, bottoni e tutto il resto.

Quanto esaminato finora è utile per costruire degli script da eseguire sulla linea di comando, ma con Python si può osare di più. Sono stati implementati diversi moduli che permettono di aggiungere ad un programma Python una GUI. In particolare abbiamo a disposizione 3 librerie:

  • Tkinter,
  • Win32Extension,
  • WxPython.

Tkinter

Tkinter è un modulo che permette di interfacciare Python a X-Windows. Infatti Tkinter utilizza il linguaggio Tk, utilizzato da molti anni in ambiente Unix per sviluppare software in ambiente X-Windows.

Questa libreria deve essere utilizzata da coloro che intendono sviluppare interfacce grafiche multipiattaforma, quindi programmi che devono girare su unix, linux, windows e anche per Mac.

Questa libreria ha il vantaggio di essere già compresa nella installazione standard, quindi non sono necessarie installazioni aggiuntive per iniziare a lavorare con l’interfaccia grafica.

Per utilizzare Tkinter è necessario compiere le seguenti operazioni:

  1. Importare il modulo chiamato (in modo originale) “Tkinter”.
  2. Inizializzare l’ambiente grafico richiamando la funzione “Tk()”.
  3. Ogni finestra grafica deve essere creata partendo da un oggetto base chiamato “Frame”. Il frame è un contenitore di altri oggetti grafici (che in Tk vengono chiamati “Widgets“).
  4. Dopo aver creato il frame, dobbiamo creare tutti i widgets contenuti in esso, nel nostro esempio tre bottoni e una casella di testo.
  5. Una volta definito l’aspetto grafico della applicazione, si deve richiamare la funzione mainloop() incaricata di far partire il programma e di rimanere in attesa di input dall’utente. L’input dell’utente proviene dalla azione che egli effettua con il mouse sui widgets.

Vediamo il listato completo del programma:

# importa il modulo
from tkinter import * 

# costruisce una classe che gestisce la finestra
class Application(Frame):
        # metodo che scrive un messaggio a video
        def scrivi_messaggio(self):
                self.mess["text"] = "Ciao a tutti!",
	
        # metodo che pulisce il messaggio a video
        def cancella_messaggio(self):
                self.mess["text"] = "",
	
        # metodo costruttore che crea gli oggetti grafici
        def __init__(self, master=None):
                f = Frame(master)
                f.pack()
	
                # crea il bottone di uscita (di colore rosso)
                self.esci = Button(f)
                self.esci["text"] = "QUIT"
                self.esci["fg"] = "red"
                self.esci["command"] = f.quit
                self.esci.pack({"side": "left"})

                # crea il bottone che permette di scrivere il messaggio
                self.butt_mess = Button(f)
                self.butt_mess["text"] = "Scrivi", 
                self.butt_mess["command"] = self.scrivi_messaggio
                self.butt_mess.pack({"side": "left"})
		
                # crea il bottone che permette di pulire il messaggio
                self.butt_canc_mess = Button(f)
                self.butt_canc_mess["text"] = "Cancella",
                self.butt_canc_mess["command"] = self.cancella_messaggio
                self.butt_canc_mess.pack({"side": "left"})
		
                # crea l'oggetto grafico che contiene il messaggio
                self.mess = Message(f)
                self.mess["text"] = "",
        
                self.mess.pack({"side": "left"})

# corpo principale del programma
finestra = Tk()
app = Application(finestra)
finestra.mainloop()

Ecco come si presenta graficamente la applicazione:

figura

Il codice è commentato per far capire i vari passaggi. Abbiamo creato una classe, denominata “Applicazione”, che contiene i dati e le operazioni necessarie alla costruzione della interfaccia grafica. I dati sono stati creati dinamicamente al momento della loro assegnazione e sono i seguenti:

  • L’oggetto esci che è il bottone di uscita;
  • L’oggetto butt_mess che è il bottone che scrive il messaggio;
  • L’oggetto butt_canc_mess che è il bottone che cancella il messaggio;
  • L’oggetto mess che è la zona grafica che contiene il messaggio.

Per ciascun oggetto abbiamo effettuato 3 operazioni:

  • Creare un’istanza;
  • Inizializzare alcuni dati membro che ne controllano l’aspetto grafico;
  • Chiamare la funziona pack che mostra gli oggetti a video.

Per quanto concerne i bottoni, il dato membro command richiede il nome della funzione che risponde all’evento della pressione del tasto. Infatti quando viene premuto il tasto butt_mess, Python invoca la funzione scrivi_messaggio.

Il corpo principale del programma, in fondo al codice, non fa altro che eseguire le tre operazioni principali che abbiamo elencato.

Il modulo è ricco di oggetti grafici di ogni tipo e si può scaricare dal sito di Python un manuale in inglese, Tkinter Life Preserver, con la spiegazione di tutti gli oggetti.

Win32Extension

Win32Extension è famiglia di moduli per costruire interfacce grafiche in ambiente Microsoft Windows. Si tratta di una vasta raccolta di moduli, scritti da Mark Hammond, che permettono di utilizzare le API Win 32 di Windows e le MFC (Microsoft Foundation Class).

Questa libreria deve essere utilizzata da coloro che sono interessati a lavorare esclusivamente in ambiente Windows, infatti in tal caso si possono sfruttare tutte le potenzialità del sistema di Redmond.

Per utilizzare le librerie di Mark Hammond è molto importante conoscere il mondo Windows, e in particolare le Api Win32. Non approfondiamo qui l’argomento (troppo vasto) ma esaminiamo un esempio con qualche piccola spiegazione.

Il processo di creazione di una finestra in windows è piuttosto articolato, è necessario svolgere i seguenti passi:

  1. Si deve scaricare la libreria Pywin e installarla.
  2. Si deve creare una classe di appartenenza della finestra. Tale classe definisce le funzionalità della finestra, ad esempio quale funzione è responsabile della sua gestione. In windows infatti, per ogni finestra grafica, esiste una funzione che gestisce completamente tale finestra.
  3. Si deve registrare in Windows la classe appena creata, in modo che esso ne venga a conoscenza. Questa operazione in python si svolge richiamando la funzione win32ui.RegisterWndClass
  4. Si deve creare l’oggetto finestra con tutte le sue caratteristiche grafiche. Questa operazione in Python si svolge richiamando la funzione CreateWindowEx
  5. Si deve richiamare una funzione, denominata ShowWindow, incaricata di mostrare a video il risultato della finestra.
# importa  i moduli necessari
import win32con
import win32ui
from pywin.mfc import window, dialog, thread, afxres

# classe che crea la finestra (eredita da window.Wnd)
class HelloWindow(window.Wnd):
        def __init__(self):
                # crea un oggetto finestra
                window.Wnd.__init__(self, win32ui.CreateWnd())

                classe = win32ui.RegisterWndClass(0, 0, win32con.COLOR_WINDOW + 1)
                zona = (100, 100, 400, 300)
                # Dice a Windows di creare la finestra 
                # con tutte le sue caratteristiche

                self._obj_.CreateWindowEx(win32con.WS_EX_CLIENTEDGE, classe,'Ciao a tutti!', win32con.WS_OVERLAPPEDWINDOW, zona, None, 0, None)

# classe che definisce la applicazione (eredita da thread.WinApp)
class HelloApp(thread.WinApp):

        # metodo che inizializza l'istanza grafica della applicazione
        def InitInstance(self):
                self.frame = HelloWindow()
                self.frame.ShowWindow(win32con.SW_SHOWNORMAL)

				# indica a Windows che si tratta della finestra
				# principale della applicazione
	
                self.SetMainFrame(self.frame)

# corpo principale del programma, istanzia la applicazione
app = HelloApp()

Osservando il codice si possono fare le seguenti osservazioni:

  • è necessario importare un insieme di moduli che definiscono tutte le classi di windows. Ad esempio il modulo “win32con” contiene tutte le costanti utilizzate nelle Api Win32.
  • Il corpo principale del programma richiama semplicemente una classe, denominata “HelloApp”, che gestisce la funzione responsabile della finestra grafica.
  • La classe “HelloApp” richiama automaticamente il metodo “InitInstance”. Tale chiamata è contenuta nel costruttore della classe “thread.WinApp“. Infatti, utilizzando le MFC si deve programmare solamente effettuando l’overloading dei metodi che si devono personalizzare. In questo esempio la classe “HelloApp” ridefinisce il metodo “InitInstance” al fine di indicare a windows di caricare la nostra nuova finestra. Quindi il programmatore perde la classica sequenzialità delle operazioni e deve conoscere molto bene ciò che avviene nelle classi madri da cui si deriva.
  • nel metodo “InitInstance” vengono svolte tutte le operazioni, compresa la creazione di un oggetto della classe “HelloWindow”, incaricata di definire le caratteristiche grafiche della finestra.
figura

Questa applicazione è veramente minimale, in quanto si limita a mostrare una finestra vuota con il titolo “Ciao a tutti!”

WxPython

WxPython permette di creare interfacce grafiche portabili tra diverse piattaforme. È una libreria basata sulla WxWindows, la quale implementa l’intera struttura in C++. Attualmente WxWindows (e di conseguenza WxPython) supporta MS Windows, Unix con GTK+, Unix con Motif, e Mac. Questa libreria è simile a Tkinter, ma più moderna e potente.

Per utilizzare WxPython è necessario compiere le seguenti operazioni:

  1. Installare il modulo. Dalla versione 3 di Python deve essere utilizzato il progetto Phoenix
  2. Importare il modulo “wx”.
  3. Creare una classe derivata da “WxApp”, la quale rappresenta l’intera applicazione. La classe “WxApp” gestisce il sistema dei messaggi e il loop degli eventi.
  4. Nel metodo “OnInit” di WxApp è necessario inizializzare l’applicazione. In particolare creare il frame e mostrare la finestra. Il frame rappresenta la finestra principale.

Vediamo il listato completo del programma:

from wx import *

class MyApp(wxApp):	# deriva la classe applicazione
	def OnInit(self):
		frame = wxFrame(NULL, -1, "Ciao da wxPython")	#creo il frame
		frame.Show(true)	#mostro il frame
		return true

app = MyApp(0)	# istanzio l'applicazione
app.MainLoop()	# faccio partire il loop che gestisce gli eventi

Ecco come si presenta graficamente la applicazione:

Anche in questo caso i commenti al codice servono a spiegare i vari passaggi. Si può notare che tutta la libreria è organizzata ad oggetti. Infatti abbiamo derivato la classe applicazione e ne abbiamo personalizzato il comportamento.

Il corpo principale del programma, in fondo al codice, non fa altro che istanziare la classe applicazione e far partire il loop che aspetta input dall’utente e gestisce gli eventi.

L’esempio è semplicissimo, il passo successivo sarebbe quello di creare dei controlli specifici all’interno del frame.

Tutte le lezioni

1 ... 20 21 22 ... 24

Se vuoi aggiornamenti su GUI inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su GUI

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy