Pygtk
Una notte insonne può rendere qualche cosa.
Stavo cercando una alternativa al C++ per produrre rapidamente qualche utility con interfaccia grafica; l'idea era di creare applicazioni semplici allo stesso tipo dei script bash che si trovano in queste pagine, ma utilizzare un interfaccia grafica per permettere all'utente di inserire o modificare agilmente più cose. Un esempio potrebbe essere un interfaccia grafica al comando mencoder il quale (definendo molte opzioni) permette di (de)codificare video e dvd.
Dopo una disperata ricerca dove avrei voluto scegliere linguaggi come PERL o RUBY, ho scelto per iniziare PYTHON perché sembrerebbe facile da apprendere e molto usato (da GOOGLE per esempio) e perciò con un futuro promettente. Per rendere la cosa più interessante ho aggiunto il framework PureMVC che è disponibile per tutti i linguaggi citati (C++ compreso).
Python + GTK (pygtk) con Glade e PureMVC: 6/8 ore
Requisiti (in ambiente Debian-like):
apt-get install python-gtk2 python-glade2 glade python-wxgtk2.8
Ho usato Debian stable (squeeze 6.0) e Geany come editor, non ho trovato IDE più utili o più interessanti. Utilizzo inoltre git come repository locale per avere lo storico dei cambiamenti, con gitg come GUI e diffuse come comparatore (anche se giudico kdiff3 superiore)
apt-get install git gitg diffuse
Prima tappa: preparare l'ambiente
mkdir pygtk # una directory di lavoro cd pygtk git init . # optional: crea il repository echo \*.pyc > .gitignore # optional: git non considererà i file precompilati generati da python git add .gitignore # optional git commit -m ".gitignore: *.pyc" # optional wget http://puremvc.org/pages/downloads/Python/PureMVC_Python.zip unzip PureMVC_Python.zip mv PureMVC_Python_1_2/src/puremvc . rm -Rf PureMVC_Python.zip PureMVC_Python_1_2 git add puremvc # optional git commit -m "puremvc added" # optional geany main.py
Struttura del programma
Grazie al framework PureMVC avremo i sorgenti del programma bem divisi in sottocartelle, divise per concetto di layers: la parte del programma che si occupa di interfacciarsi con l'utente (ui_gtk), la parte che ottenuta l'azione dell'utente chiama un comando (view), il comando che verifica lo stato e i parametri ottenuti e modifica lo stato del programma e i dati (controller), la parte che fornisce i dati al comando e che il comando chiama per modificare i dati (model) e che può notificare il cambiamento dei dati alla parte che chiamò il comando (view) e che può quindi informare i cambiamenti all'interfaccia grafica (ui_gtk).
avremo quindi:
pygtk/ application/ controller/ define/ domain/ dto/ model/ puremvc/ ui/ ui_gtk/ ui_wx/ view/
Come avrete notato ho aggiunto qualche directory in più: PureMVC separa così bene il programma che ci permette di utilizzare diverse interfacce grafiche (in questo caso GTK o WxWidget). Per far questo ho definito interfaces alle classi che inizializzano la parte grafica e mostrano la finestra del programma. In questo modo potrei aggiungere un file di configurazione per scegliere se utilizare una o l'altra libreria grafica. Per questo esempio instanzio la classe specifica dell'interfaccia GTK nel file main.py e la passo alla classe application/Application.py che si occupa di inizializzare la parte grafica e il framework PureMVC. Ho messo quindi nella directory ui/ le intrefaces e in ui_gtk/ e ui_wx/ le classi grafiche specifiche. Nella directory define/ ho aggiunto un file comune, usato in varie classi, per definire i nomi degli eventi ai quali voglio associare una determinata azione. Nella directory domain ho messo le classi che si occupano di fare il lavoro vero e proprio (per esempio nel caso di un programma per convertire i video ci si troverebbe la classe Converter che si occuperebbe di chiamare il comando mencoder con le opzioni corrette). Nella directory dto/ ho messo delle classi che utilizzo solamente per trasferire comodamente informazioni da una parte all'altra del programma (Data Transfer Object, vedi anche POCO o POJO).
Sembra tutto più complicato, ma in realtà è solamente ben organizzato, in modo che il programma può crescere (si possono aggiungere finestre, funzionalità, ecc) senza che diventi un miscuglio irriconoscibile.
Seconda tappa: preparare la struttura.
Non ho capito bene come funziona python in questa cosa: sembrerebbe che se organizzo il programma in cartelle (e in realtà in pacchetti) lui vuole che per ogni cartella esista un file con il nome __init__.py , perciò senza perderci troppo tempo creiamo questa struttura:
for DIR in application controller define dto domain model ui ui_gtk ui_wx view; do mkdir $DIR; touch $DIR/__init__.py; done git add --all # optional git commit -m "initial structure added" # optional
Un esempio non troppo complicato é il seguente:
(Convertitore di base decimale->esadecimale->binario ecc.)