martedì 27 aprile 2010

Python - finestre, pulsanti et al.

Ma Python si usa solo "da terminale", come si usava prima di X, Mac, Windows?
Questa la domanda difficile che qualcuno mi ha rivolto, su Facebook, non qui. La risposta è sì e no. Se sembra troppo breve potrei dilungarmi ma poi diventerebbe troppo lunga; diciamo, per semplificare, che Python è legato alla Weltanschauung di Unix/Linux, agli antipodi di quella di Mac e Windows.
Ma si possono benissimo fare applicazioni grafiche, oggi vediamo l'equivalente di "Hello World!", l'ho testato sia su Ubuntu che su Windows Vista.
Aggiornato per problemi di indentazione, speriamo che...

#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

import wx

class MyFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, \
size = (200, 150), pos = (100, 200), title = "Hello!")
# su Linux si può aggiungere: style = wx.CAPTION | wx.CLOSE_BOX)

self.bitmap = wx.Bitmap('wh-b.png')
wx.EVT_PAINT(self, self.OnPaint)
self.SetIcon(wx.Icon('wh-i.png', wx.wx.BITMAP_TYPE_PNG))

self.label1 = wx.StaticText(self, label="nome", pos=(10, 12))
self.label11 = wx.StaticText(self, pos=(10,20))
self.edit1 = wx.TextCtrl(self, size=wx.Size(150, -1), pos=(25, 30))

self.button = wx.Button(self, label="OK", pos = (50, 80), \
size = wx.Size(100, 24))
self.button.Bind(wx.EVT_BUTTON, self.on_button_OK)

def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.DrawBitmap(self.bitmap, 1, 1)

def on_button_OK(self, event):
nome = self.edit1.GetValue().strip()
msg = "Hello " + nome + "\nhave a nice day!" + "\n\nvisto che facile?"
titolo = "ciao"
wx.MessageBox(msg, titolo)

class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1)
frame.Show(True)
self.SetTopWindow(frame)
return True

app = MyApp()
app.MainLoop()


Codice troppo lungo e misterioso? No, dai! Si importa il modulo wx e si costruisce una classe (MyFrame) all'interno della quale posizioniamo un'immagine di sfondo, un'etichetta, un pulsante e il metodo di quest'ultimo quando viene clickato. Definiamo poi la classe (MyApp) che contiene il frame precedentemente definito. A questo punto istanziamo MyApp ed è tutto. Vero che così è molto più semplice? (Quando una riga è troppo lunga si può spezzare con \).
Abbiamo bisogno di due immagini:
wh-b.png con dimensioni di 200x150 pixel, usato come sfondo della finestra;




wx-i.png le dimensioni non sono vincolanti, meglio se è quadrata, usata come icona dell'applicazione, su Windows non funziona e non so perché.





Le due immagini devono essere nella stessa directory (cartella) dello script (che io ho chiamato whello.py). Si esegue al solito con python whello.py o rendendolo eseguibile con chmod. Per gli utenti Windows ne parlo tra più avanti.
Per Linux basta installare il pacchetto wxPython, se non è già installato e il gioco è fatto. Per testare se abbiamo già wx basta lanciare in modo interattivo Python e digitare "import wx"; se non protesta c'è già.

Due parole per i windoziani. Pyhton si deve eseguire dentro al terminale, lo trovate in Start/Tutti i programmi/Accessori.
Dovete andare nella directory dove avete i tre files dell'applicazione con cd. Supponiamo, come nel mio caso, che si trovino nel disco F:, nella cartella \whfin e che Python sia stato installato sul disco C: nella cartella \Python26. Allora, dentro al terminale i comandi saranno:
F:
cd \whfin
c:\python26\python whello.py
Un'ultima osservazione, anzi due. La finestra era in origine molto più piccola (120x90) e la barra del titolo aveva solo il pulsante di chiusura. Ho dovuto modificarla perché su Windows la finestra non veniva visualizzata correttamente. A quanto pare i caratteri accentati non piacciono a wx.
Scaricare wx da http://www.wxpython.org/download.php, per Windows ho usato wxPython runtime per Python 2.6.
Esistono anche programmi per "disegnare" e "draggare" i componenti grafici, nessuno lontanamente funzionale come Delphi: Matteo ti devi rassegnare.

8 commenti:

  1. ciao, solo una segnalazione.
    Io ho giochicchiato con le Qt nel passato, versione C++, mi erano piaciute parecchio. So che ci sono dei "bindings" per Python, ma non li so usare. Tra l'altro, le Qt dovrebbero essere free a tutti gli effetti adesso.

    RispondiElimina
  2. Nella pausa pranzo ho provato a eseguire il tuo programmino, e mi salta fuori subito che:

    Traceback (most recent call last):
    File "wx.py", line 3, in
    import wx
    File "/home/lipari/devel/python/wx.py", line 5, in
    class MyFrame(wx.Frame):
    AttributeError: 'module' object has no attribute 'Frame'
    lipari@lipari$ python wx.py
    File "wx.py", line 7
    def __init__(self, parent, id):
    ^
    IndentationError: expected an indented block


    (sono saltati dei tab davanti ai def?)

    Ciao a stasera.

    RispondiElimina
  3. Caro juhan, a parte il fatto che il Delphi è molto più agevole e immediato per finestre, pulsanti etc.. (ma non preoccuparti è solo una mia impessione - nulla toglie al Python),tutti i programmi precedentemente pubblicati hanno perfettamente funzionato, purtroppo questo mi dice " There's an error in your program: expected an indented block"....

    Complimenti comunque a questo e agli articoli precedenti (se devo essere sincero per questo programma il codice è un pochino corposo da scrivere e quando le finestre si fanno più complesse... aiutoooooooo)

    RispondiElimina
  4. Ops! Ma è Blogger che non interpreta i tab anche se dentro al tag <pre&gt (anche questo non so se viene visualizzato come minore-pre-maggiore).
    Ho corretto il codice html mettendo spazi anziché tabs, forse adesso...

    RispondiElimina
  5. Nel commento precedente ho dimenticato un ";", sostituite mentalmente <pre&gt con <pre>
    Mi sa che a breve serve un altro post, senza codice, dove si parla di Qt, Boa Constructor, wxFormBuilder, wxGlade e chissà cos'altro.

    RispondiElimina
  6. Certo che se fosse possibile inserire nel post uno zip... E forse lo è, qualcuno sa come si fa?
    OK sto uscendo intrigato nella cosa... ma poi mi passa, spero.

    RispondiElimina
  7. Et Voilà...ora funziona perfettamente!!!grazie juhan.
    In effetti era propio solo un problema di indentatura.

    RispondiElimina
  8. È Blogger. Quando ho provato in composizione era OK, appena posti il post (ahem...) i tab spariscono. Non si testa mai abbastanza. Ma prossimamente ci saranno novità.
    E sto preparando un post su quanto promesso, solo che sono in ritardo inseguendo altre cose. E poi oggi esce Lucid Lynx (che però rimando di un tot).

    RispondiElimina

Attenzione: I commenti a vecchi post potrebbero essere moderati