Il 0% ha trovato utile questo documento (0 voti)
2 visualizzazioni20 pagine

Full Circle. Programmare in Python Volume 3 (Fullcircle Ubuntu Linux Magazine) (ITA)

Full Circle Magazine è una rivista gratuita e indipendente dedicata alla comunità Ubuntu, che pubblica articoli tecnici e contenuti inviati dai lettori. Questa edizione speciale raccoglie articoli sulla programmazione in Python, in particolare sulla creazione di applicazioni client/server. Il documento fornisce esempi pratici di codice e spiega i concetti fondamentali del networking in Python.
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
2 visualizzazioni20 pagine

Full Circle. Programmare in Python Volume 3 (Fullcircle Ubuntu Linux Magazine) (ITA)

Full Circle Magazine è una rivista gratuita e indipendente dedicata alla comunità Ubuntu, che pubblica articoli tecnici e contenuti inviati dai lettori. Questa edizione speciale raccoglie articoli sulla programmazione in Python, in particolare sulla creazione di applicazioni client/server. Il documento fornisce esempi pratici di codice e spiega i concetti fondamentali del networking in Python.
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 20

full circle

SE
ED E P
RI
IZ RO
IO G
N RA
E
SP MM
LA RIVISTA INDIPENDENTE PER LA COMUNITÀ LINUX UBUNTU

EC A
EDIZIONE SPECIALE SERIE PROGRAMMAZIONE

IA ZIO
LE N
E
PROGRAMMARE
IN PYTHON
VOLUME 3
full circle magazine n. 31 1⁠⁠ indice ^
Full Circle Magazine non è affiliata né sostenuta da Canonical Ltd.
Full Circle
Cos'è Full Circle Come contattarci
Full Circle è una rivista gratuita e Sito web:
indipendente, dedicata alla famiglia http://www.fullcirclemagazine.org/
Ubuntu dei sistemi operativi Linux. Forum:
Ogni mese pubblica utili articoli LA RIVISTA INDIPENDENTE PER LA COMUNITÀ LINUX UBUNTU http://ubuntuforums.org/forumdispl
tecnici e articoli inviati dai lettori. ay.php?f=270
IRC:
Full Circle ha anche un podcast di Ecco a voi un altro Speciale monotematico! #fullcirclemagazine su
supporto, il Full Circle Podcast, con gli chat.freenode.net
stessi argomenti della rivista e altre Come richiesto dai nostri lettori, stiamo assemblando in edizioni dedicate
interessanti notizie. alcuni degli articoli pubblicati in serie. Gruppo editoriale
Capo redattore: Ronnie Tucker
Quella che avete davanti è la ristampa della serie Programmare in Python, (aka: RonnieTucker)
parti 17-21, pubblicata nei numeri 43-47: niente di speciale, giusto quello [email protected]
che abbiamo già pubblicato. Webmaster: Rob Kerfia
Si prega di notare che questa
(aka: admin / linuxgeekery-
edizione speciale viene fornita senza
Vi chiediamo, però, di badare alla data di pubblicazione: le versioni attuali di [email protected]
alcuna garanzia: né chi ha contribuito
hardware e software potrebbero essere diverse rispetto ad allora. Podcaster: Robin Catling
né la rivista Full Circle hanno alcuna
Controllate il vostro hardware e il vostro software prima di provare quanto (aka RobinCatling)
responsabilità circa perdite di dati o
descritto nelle guide di queste edizioni speciali. Potreste avere versioni più [email protected]
danni che possano derivare ai
recenti del software installato o disponibile nei repository delle vostre Manager delle comunicazioni:
computer o alle apparecchiature dei
distribuzioni. Robert Clipsham
lettori dall'applicazione di quanto
(aka: mrmonday) -
pubblicato.
Buon divertimento! [email protected]

Gli articoli contenuti in questa rivista sono stati rilasciati sotto la licenza Creative Commons Attribuzione - Non commerciale - Condividi allo stesso modo
3.0. Ciò significa che potete adattare, copiare, distribuire e inviare gli articoli ma solo sotto le seguenti condizioni: dovete attribuire il lavoro all'autore
originale in una qualche forma (almeno un nome, un'email o un indirizzo Internet) e a questa rivista col suo nome ("Full Circle Magazine") e con suo
indirizzo Internet www.fullcirclemagazine.org (ma non attribuire il/gli articolo/i in alcun modo che lasci intendere che gli autori e la rivista abbiano esplicitamente autorizzato voi
o l'uso che fate dell'opera). Se alterate, trasformate o create un'opera su questo lavoro dovete distribuire il lavoro risultante con la stessa licenza o una simile o compatibile.
Full Circle magazine è completamente indipendente da Canonical, lo sponsor dei progetti di Ubuntu, e i punti di vista e le opinioni espresse nella rivista non
sono in alcun modo da attribuire o approvati da Canonical.

Full Circle Magazine


HOW0TO
Scritto da Greg Walters
Programmare in Python 0 Parte 17

M
entre stavo realizzato il programma delle server. Lo facciamo attraverso (pensate al filo) al server. Se molti
concludendo l'ultimo ricette? Era un esempio MOLTO quello che chiamiamo pipe o client sono connessi al server, ogni
articolo della nostra semplice (e nemmeno tanto bello) socket. Se da piccoli avete creato client utilizzerà una lattina propria
serie, ho ricevuto una di applicazione client/server. Il un telefono con filo e lattine allora e il povero server deve avere lo
mail riguardante una gara di database SQLITE era il server, avete un'idea di cosa sto parlando. stesso numero di lattine tutte
programmazione. Anche se non l'applicazione che abbiamo scritto Altrimenti, lasciate che ve lo saldamente collegate a quelle
abbiamo tempo di occuparcene, era il client. Un esempio più descriva. Prima di tutto, dovevate corrispondenti dei client.
diversi siti propongono gare del calzante è il seguente. ottenere da vostra madre un paio di
genere durante l'anno. Le Consideriamo un database su un lattine di fagioli in scatola o Creiamo un client/server
informazioni sono reperibili computer ubicato diversi piani qualcosa di simile. Quindi, dopo semplice. Inizieremo dal server. In
all'indirizzo lontano dal vostro ufficio. Contiene averle pulite per bene le si portava pseudo codice, ecco cosa accade.
http://www.freiesmagazin.de/third informazioni sull'inventario del in garage. Si usava un chiodo sottile
_programming_contest, se siete negozio in cui lavorate. Usate un e un martello per creare un Crea un socket
interessati. Tutto questo mi ha registratore di cassa (uno di 10) forellino sul fondo di ciascuna. Recupera il nome del server
fatto pensare che non abbiamo mai all'interno del negozio. Ciascuno di Quindi bisognava procurarsi 405 Seleziona una porta
parlato di una vera questi registratori rappresenta un metri di filo (ancora dalla amata Associa il socket all'indirizzo e
programmazione Client/Server. client e il database posizionato da mamma), far passare l'estremità alla porta
Quindi, con questo obiettivo in qualche parte è il server. attraverso ciascuna lattina e Resta in attesa della connessione
mente ci addentriamo realizzare un nodo per evitare che Se connesso...
nell'argomento e vediamo dove ci Anche se non creeremo quel l'estremità fuoriuscisse. Quindi ci si Accetta la connessione
porta. genere di sistema, possiamo incontrava con il miglior amico e, Stampa che abbiamo la
impararne i concetti base. tenendo ben teso il filo, si parlava connessione
Cos'è un'applicazione nella lattina mentre il nostro amico Chiudi la connessione
Client/Server? Semplicemente, La prima cosa a cui bisogna teneva l'altra sull'orecchio. Le
ogniqualvolta usate un programma pensare è l'ubicazione del nostro vibrazioni del fondo si propagano Il vero codice per il nostro server
(o anche una interfaccia web) che server. Molte persone hanno solo lungo il filo teso provocando la si trova nella pagina seguente, in
accede ai dati di un'altra un computer nella propria casa. vibrazione del fondo dell'altra basso a sinistra.
applicazione o computer allora Altre ne possiedono 7 o 8. lattina. Ovviamente avreste potuto
state usando un sistema sentire anche senza, ma il punto Allora, abbiamo creato il socket,
client/server. Consideriamo un Per utilizzare il sistema non è questo. Era divertente. Il recuperato il nome della macchina
esempio che ci è familiare. client/server, bisogna connettersi socket è più o meno la stessa cosa. host su cui il server è in esecuzione,
Ricordate quando abbiamo dalla macchina client a quella Il client ha una connessione diretta associato il socket alla porta e

full circle magazine #43 7 contents ^


PROGRAMMARE IN PYTHON 0 PARTE 17
#!/usr/bin/env python
iniziato ad ascoltare. Quando e su quello client... # client2.py
riceviamo una richiesta di
connessione, l'accettiamo, Hello and Goodbye from socket import *
from time import time
stampiamo il fatto che siamo
from time import sleep
connessi, inviamo "Hello and Quindi tutto molto semplice.
import sys
Goodbye" e chiudiamo il socket. Ora rendiamo il tutto un po' più BUFSIZE = 4096
realistico. Creeremo un server che
effettivamente fa qualcosa. Il class CmdLine:
Ora abbiamo bisogno del client
def __init__(self,host):
per rendere il tutto funzionante codice della seconda versione lo
self.HOST = host
(mostrato in basso a destra). trovate qui: self.PORT = 29876
http://fullcirclemagazine.pastebin.c self.ADDR = (self.HOST,self.PORT)
om/Az8vNUv7 self.sock = None
Il codice è simile a quello del
server ma, in questo caso, ci def makeConnection(self):
connettiamo, stampiamo quanto Analizziamolo a blocchi. Dopo la self.sock = socket( AF_INET,SOCK_STREAM)
ricevuto e chiudiamo il socket. sezione degli import, impostiamo self.sock.connect(self.ADDR)
alcune variabili. BUFSIZ contiene le
def sendCmd(self, cmd):
L'output dei programmi è molto dimensioni del buffer che useremo
self.sock.send(cmd)
prevedibile. Sul lato server per conservare l'informazione
otteniamo... ricevuta dal client. Impostiamo def getResults(self):
anche la porta su cui ascoltare e data = self.sock.recv(BUFSIZE)
print data
My hostname is earth una lista con l'host e il numero della
porta. if __name__ == '__main__':
I'm now connected to
conn = CmdLine('localhost')
('127.0.1.1', 45879)
Quindi creiamo la conn.makeConnection()
conn.sendCmd('ls -al')
#!/usr/bin/env python
classe ServCmd.
conn.getResults()
#server1.py Nella funzione conn.sendCmd('BYE')
import socket __init__ inseriamo
soc = socket.socket() il socket e vi
hostname = socket.gethostname() #!/usr/bin/python
print "My hostname is ", hostname
associamo # client1.py
port = 21000 l'interfaccia. Nella #====================
soc.bind((hostname,port)) funzione run import socket
soc.listen(5) iniziamo ad
while True: soc = socket.socket()
con,address = soc.accept()
ascoltare e hostname = socket.gethostname()
print "I'm now connected to ",address aspettiamo il port = 21000
con.send("Hello and Goodbye") comando dal
con.close() client. soc.connect((hostname, port))
print soc.recv(1024)
full circle magazine #43 8 soc.close contents ^
PROGRAMMARE IN PYTHON 0 PARTE 17
Quando ne riceviamo uno, -rw-r--r-- 1 greg greg 760 server. Per la mia configurazione
usiamo la routine os.popen(). 2010-11-08 05:28 client2a.py~ casalinga uso la seguente riga:
-rw-r--r-- 1 greg greg 737 Cercasi idee e
Questa si occupa di creare un 2010-11-08 05:25 client2.py
terminale ed eseguire il comando. -rw-r--r-- 1 greg greg 733 conn = scrittori
2010-11-08 04:37 client2.py~ CmdLine('192.168.2.12')
Quindi il client (in alto a destra), -rw-r--r-- 1 greg greg 1595
2010-11-08 05:30 client2.pyc Siamo così in grado di inviare
la cui creazione è un compito -rw-r--r-- 1 greg greg 449
semplice. informazioni avanti e indietro da
2010-11-07 07:38 ping2.py
-rw-r--r-- 1 greg greg 466 una macchina (o terminale) all'altra. Su LaunchPad abbiamo creato le
Saltiamo tutto eccetto il 2010-11-07 10:01 pagine del progetto e della squadra
python_client1.py La prossima volta renderemo più Full Circle. L'idea è quella che i non0
comando di invio, dato che ora -rw-r--r-- 1 greg greg 466
avete abbastanza informazioni per robusta la nostra applicazione. scrittori possono collegarsi alla
2010-11-07 10:01
comprenderlo da soli. La riga python_client1.py~ pagina, fare clic su "Answers" in alto
conn.sendCmd() (riga 31) invia una -rw-r--r-- 1 greg greg 691 e lasciare idee per articoli, ma vi
2010-11-07 09:51 prego siate specifici! Non inserite
semplice richiesta ls 0al. Ecco come python_server1.py
appare la risposta nel mio caso. La -rw-r--r-- 1 greg greg 666 solo "articolo sui server" ma
vostra potrebbe essere differente. 2010-11-06 06:57 indicate anche cosa il server
python_server1.py~ dovrebbe fare!
-rw-r--r-- 1 greg greg 445
Server 2010-11-04 06:29 re-test1.py
I lettori che volessero scrivere un
-rw-r--r-- 1 greg greg 1318
2010-11-08 05:49 server2a.py articolo ma sono a corto di idee,
python server2.py
...listening -rw-r--r-- 1 greg greg 1302 possono registrarsi alla pagina del
...connected: 2010-11-08 05:30 server2a.py~ gruppo Full Circle quindi auto0
('127.0.0.1',42198) -rw-r--r-- 1 greg greg 1268
2010-11-06 08:02 server2.py assegnarsi gli articoli proposti e
Command received - ls -al iniziare a scrivere! Chiediamo che se
Command received - BYE -rw-r--r-- 1 greg greg 1445
...listening 2010-11-06 07:50 server2.py~ non è possibile scrivere l'articolo
-rw-r--r-- 1 greg greg 2279 nel giro di alcune settimane (un
2010-11-08 05:30 server2.pyc
mese circa) la richiesta venga
Client riaperta per permettere a
Possiamo anche connetterci da
qualcun'altro di adottarla.
python client2a.py un'altra macchina senza cambiare
total 72 nulla, con la sola eccezione di conn Greg Walters è il proprietario della
drwxr-xr-x 2 greg greg 4096 RainyDay Solutions, LLC, una società Pagina del progetto, per le idee:
2010-11-08 05:49 . = CmdLine('localhost') (riga 29) nel
di consulenza in Aurora, Colorado e https://launchpad.net/fullcircle
drwxr-xr-x 5 greg greg 4096 programma client. In questo caso, programma dal 1972. Ama cucinare, Gruppo degli scrittori:
2010-11-04 06:29 .. cambiate 'localhost' con l'indirizzo fare escursioni, ascoltare musica e
-rw-r--r-- 1 greg greg 751 https://launchpad.net/~fullcircle
IP della macchina che esegue il passare il tempo con la sua famiglia.
2010-11-08 05:31 client2a.py

full circle magazine #43 9 contents ^


HOW0TO
Scritto da Greg Walters
Programmare in Python 0 Parte 18

L
'ultima volta abbiamo la scacchiera con degli "0" e quindi Proseguiamo con la porzione
creato un sistema [0][0] | [0][1] | [0][2] inviare la "rappresentazione" della della routine che riguarda Move
[1][0] | [1][1] | [1][2] tavola al client. (mostrata in basso). Prima
client/server molto [2][0] | [2][1] | [2][2]
semplice. Questa volta lo controlliamo i primi quattro
espanderemo un po'. Il server sarà Il comando "Move" è un caratteri del comando passato per
Così, partendo dal codice del
una tavola e un validatore del gioco comando composto in quanto vedere se corrispondono a "Move".
server del mese passato, nella
del Tris (o cerchi e croci). La parte contiene il comando e la posizione In caso affermativo estraiamo la
funzione __init__ inseriamo le
client fungerà da input/output. nella quale il giocatore vuole parte restante della stringa a
seguenti righe:
muoversi. Per esempio, "Move A3". partire dalla posizione 5 (dato che
Inizieremo usando lo stesso # The next three lines are Analizzando il comando ricaveremo l'indice base è 0) e l'assegniamo alla
codice del server dell'ultima volta e new... tre informazioni, lo stesso comando variabile chiamata position. Quindi
lo modificheremo strada facendo. self.player = 1 "move", la riga e la colonna. Per controlliamo se il primo carattere è
self.gameboard = [['-','- finire, il comando "GOODB\E" una "A", "B", o "C". Rappresenta la
Se non lo avete ancora salvato, ','-'],['-','-','-'],['-','-
andate su ','-']] resetta, semplicemente, la tavola riga inviata dal client. Quindi
http://fullcirclemagazine.pastebin.c da gioco per un'altra partita. recuperiamo l'intero del carattere
om/UhquYN4N, recuperate il codice self.run() successivo e avremo la nostra
e proseguite. Il primo cambiamento Allora, riceviamo il comando dal colonna:
riguarda la routine __init__ dove Le routine run, listen, e servCmd client nella funzione procCmd.
inizializzeremo due nuove variabili, non sono cambiate, quindi ci Quindi lo analizziamo per vedere if cmd[:4] == 'Move':
self.player e self.gameboard. concentriamo sulle modifiche a cosa fare. All'interno della routine print "MOVE COMMAND"
procCmd. position = cmd[5:]
Gameboard è un semplice elenco di procCmd, portiamoci alla 5a riga e if position[0] == 'A':
liste o un array base. Possiamo rimuoviamo tutto il codice che row = 0
accedervi come segue Nell'articolo dell'ultima volta, il segue la riga contenente "if elif position[0] == 'B':
(maggiormente intuibile di una lista server attendeva un comando dal self.processingloop:". Ora row = 1
piatta). Questa lista conterrà i client e lo inviava alla funzione imposteremo i comandi così come li elif position[0] == 'C':
nostri dati. Ogni cella accetterà tre os.popen. Questa volta abbiamo definiti. Ecco il codice per row = 2
possibili valori. "0" indica una cella analizzeremo il comando ricevuto. il comando Start: else:
vuota, "[" una cella occupata dal In questo caso resteremo in attesa self.cli.send('Invalid
di tre comandi differenti. Sono if self.processingloop: position')
giocatore 1 e "O" una occupata dal return
"Start", "Move", e "GOODB\E". if cmd == 'Start':
giocatore 2. La griglia assomiglia self.InitGameBoard() col = int(position[1])-1
alla seguente quando la Quando riceviamo il comando self.PrintGameBoard(1)
rappresentiamo in due dimensioni: "Start", il server dovrà inizializzare

full circle magazine n. 44 7 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 18
A seguire, facciamo un controllo Questo conclude le modifiche Quindi, controlliamo se il Finalmente, nella pagina
rapido per assicurarci che la alla funzione procCmd. Ora tocca parametro è impostato a 0 o 1 successiva, ecco la routine usata dal
posizione della riga sia tra quelle alla funzione "inizializza la (sotto). Solo se firsttime è 0 server per controllare l'evento vittoria.
possibili: scacchiera di gioco". Tutto quello controlliamo se il giocatore attuale Abbiamo già impostato per il giocatore
che fa è impostare ciascuna ha vinto e, se è così, aggiungiamo il una "[" o "O", quindi iniziamo usando
if row < 0 or row > 2: posizione a "0", che la logica di testo "Player [ ZINS!" alla stringa un semplice ciclo for. Se ci imbattiamo
self.cli.send('Invalid
move usa per verificare che uno in uscita. Se il giocatore corrente in una vittoria, ritorniamo True. La
position')
return spazio sia vuoto: non ha vinto allora inseriamo il variabile "C" del ciclo for rappresenta
testo "Enter move...". Per finire ciascuna riga nella nostra lista di liste.
def InitGameBoard(self): inviamo la stringa al client con la Prima controlleremo ogni riga per una
Per finire, verifichiamo che la self.gameboard = [['-','-
posizione sia vuota ("0") e, se il funzione cli.send: vittoria in orizzontale:
','-'],['-','-','-'],['-','-
giocatore corrente è il numero 1, ','-']]
mettiamo una "[", altrimenti "O". if firsttime == 0:
Quindi chiamiamo la funzione La routine PrintGameBoard if self.player == 1:
PrintGameBoard con "0" come (sotto) stampa la scacchiera, chiama ret = self.checkwin("X")
else:
parametro: la funzione checkwin e imposta il ret = self.checkwin("O")
numero del giocatore. Creiamo una if ret == True:
if self.gameboard[row][col] stringa molto grande da inviare al if self.player == 1:
== '-': outp += "Player 1 WINS!"
client così da dover inserire la
if self.player == 1: else:
funzione d'ascolto una volta per outp += "Player 2 WINS!"
self.gameboard[row][col] = mossa. Il parametro firsttime è else:
"X" incluso per inviare il pritty print del if self.player == 1:
else: self.player = 2
tavolo da gioco quando il client si
else:
self.gameboard[row][col] = connette per la prima volta o self.player = 1
"O" resetta il gioco: outp += ('Enter move for player %s' %
self.player)
self.PrintGameBoard(0) self.cli.send(outp)

def PrintGameBoard(self,firsttime):
#Print the header row
outp = (' 1 2 3') + chr(13) + chr(10)
outp += (" A {0} | {1} | {2}".format(self.gameboard[0][0],self.gameboard[0][1],self.gameboard[0][2])) + chr(13)+chr(10)
outp += (' ------------')+ chr(13)+chr(10)
outp += (" B {0} | {1} | {2}".format(self.gameboard[1][0],self.gameboard[1][1],self.gameboard[1][2]))+ chr(13)+chr(10)
outp += (' ------------')+ chr(13)+chr(10)
outp += (" C {0} | {1} | {2}".format(self.gameboard[2][0],self.gameboard[2][1],self.gameboard[2][2]))+ chr(13)+chr(10)
outp += (' ------------')+ chr(13)+chr(10)
full circle magazine n. 44 8 lnglce ^
PROGRAMMARE IN PYTHON 0 PARTE 18
First, we will check each Row for a horizontal win: Il Client con ciascuno dei seguenti comandi
def checkwin(self,player): Ancora una volta, iniziamo (dovreste già avere il codice per le
#loop through rows and columns mosse A3 e B2), C1, A1, C3, B3, C2 e
dalla semplice routine creata
for c in range(0,3): quindi terminate con il comando
#check for horizontal line l'ultima volta. I cambiamenti
if self.gameboard[c][0] == player and iniziano subito dopo la chiamata a GOODB\E.
self.gameboard[c][1] == player and self.gameboard[c][2] == conn.makeConnection. Inviamo i
player:
print "*********\n\n%s wins\n\n*********" %
comandi Start, diversi Move e, per Xlteriori modifiche
player finire, Goodbye. La cosa più Ecco i "compiti per casa". Nel
playerwin = True importante da ricordare qui è che client, rimuovete i comandi
return playerwin dopo aver inviato un comando preparati per le mosse e usate
dovete attendere la risposta raw_input() per richiedere e
Next, we check each Column for a win:
#check for vertical line prima di inviarne un altro. catturare le mosse dal/dai
elif self.gameboard[0][c] == player and Immaginatela come una giocatore/i nella forma "A3" o "B2"
self.gameboard[1][c] == player and self.gameboard[2][c] == conversazione educata. Inviate la e quindi farli precedere da "Move"
player:
vostra richiesta, attendete la prima di inviare l'intero comando al
print "** %s wins **" % player
playerwin = True risposta, inviatene un'altra, server.
return playerwin attendete nuovamente, e così via.
In questo esempio usiamo Oa prossima volta
Now we check for the diagonal win from left to right...
raw_input semplicemente perchä modificheremo il nostro server
#check for diagonal win (left to right)
elif self.gameboard[0][0] == player and possiate vedere cosa avviene: per giocare come avversario.
self.gameboard[1][1] == player and self.gameboard[2][2] ==
player: if __name__ == '__main__': Il codice del Client e del Server
print "** %s wins **" % player conn =
playerwin = True CmdLine('localhost') puí essere trovato a questi
return playerwin conn.makeConnection() indirizzi:
conn.sendCmd('Start') http://fullcirclemagazine.pastebin.c
Then from right to left... conn.getResults() om/UhquYN4N o
#check for diagonal win (right to left) conn.sendCmd('Move A3')
elif self.gameboard[0][2] == player and conn.getResults() http://thedesignatedgeek.com.
self.gameboard[1][1] == player and self.gameboard[2][0] == r = raw_input("Press
player: Enter")
print "** %s wins **" % player conn.sendCmd('Move B2')
playerwin = True conn.getResults() Greg Walters è il proprietario della
return playerwin r = raw_input("Press RainyDay Solutions, LLC, una società
Enter") di consulenza in Aurora, Colorado e
Finally, if there is no win, we return false: programma dal 1972. Ama cucinare,
else: fare escursioni, ascoltare musica e
Continuate con la tripletta
playerwin = False passare il tempo con la sua famiglia.
return playerwin sendCmd, getResults, raw_input

full circle magazine n. 44 9 lnglce ^


HOW0TO
Scritto da Greg Walters
Programmare in Python 0 Parte 19

Q
uesta volta lavoreremo per
SE “O” prende uno SPIGOLO ALLORA
terminare il nostro # Scenario 1
programma 'Tris'. Tuttavia, “X” dovrebbe prendere uno degli spigoli rimasti. Non importa quale.
diversamente dalla SE “O” blocca la vittoria ALLORA
“X” prende il restante spigolo.
maggior parte dei miei altri articoli,
Termina per vincere.
non fornirí il codice. Lo farete voi. ALTRIMENTI
Comunque vi darí le regole. Dopo 18 Termnare per vincere.
mesi, avete gli strumenti e le ALTRO SE “O” prende un LATO ALLORA
# Scenario 2
conoscenze per terminare questo
“X” prende il CENTRO
progetto. Ne sono sicuro. SE “O” blocca la vittoria ALLORA
“X” prende lo spigolo che non è delimitato con nessun “O”
Per prima cosa diamo uno sguardo Termina per vincere.
ALTRIMENTI
alla logica del gioco del Tris. Yedremo
Termina per vincere.
il suo pseudo0codice. Diamo prima ALTRIMENTI
un'occhiata al tavolo da gioco. È # “O” ha preso il centro – Scenario 3
disposto così... “X” prende lo spigolo diagonalmente opposto
alla mossa iniziale
SE “O” prende uno spigolo SE “X” non prende il centro ALLORA
Spigolo| Lato | Spigolo “O” prende il Centro
“X” prende il restante spigolo
-------+--------+------- SE “X” ha preso lo spigolo E il
Termina per vincere.
Lato | Centro | Spigolo lato ALLORA
ALTRIMENTI
-------+--------+------- #Scenario 5
# Il gioco avrà un pareggio – Scenario 4
Spigolo| Lato | Spigolo “O” prende lo spigolo
Blocca la vittoria di “O”.
Blocca ogni altra possibilità di vittoria diagonalmente opposto da quello di “X”
Ora, chiunque sia "[", inizia per Pareggio. Blocca ogni possibile
vittoria per pareggiare.
primo. La miglior mossa iniziale è ALTRIMENTI
prendere uno spigolo. Uno spigolo # “X” ha preso due Lati –
Alcune possibili giocate sono essere capaci di
qualunque, non importa quale sia. Ce Scenario 6
mostrate nella prossima pagina. modificare il codice del “O” prende lo spigolo
ne occuperemo con le combinazioni
Come si puí vedere, la logica è mese scorso per confinante con entrambe le “X”
di gioco per la prima mossa di "[", SE “X” blocca la vittoria
alquanto complessa, ma puí essere adattarlo, o come
che sono indicati destra. ALLORA
facilmente ripartita in una serie di minimo scriverne uno da
“O” prende ogni lato.
istruzioni IF (notare che ho utilizzato zero per essere un Bloccare e forzare il pareggio
Il punto di vista del giocatore "O"
"Then", ma in Python non lo usiamo, semplice programma ALTRIMENTI
è mostrato in basso a destra. Termina per vincere.
utilizziamo invece ":"). Dovreste desktop Tris.
full circle magazine n. 45 7 lnglce ^
PROGRAMMARE IN PYTHON 0 PARTE 19
Scenario 1
X | - | - X | - | - X | - | - X | - | - X | - | X X | - | X X | X | X Proposte e Autori
- | - |
- | - |
-
-
- | - | -
- | - | O
- | - | -
X | - | O
O | - | -
X | - | O
O | - | -
X | - | O
O | O | -
X | - | O
O | O | -
X | - | O
Cercansi
Scenario 2
X | - | - X | - | - X | - | - X | - | - X | - | X X | - | X X | X | X
- | - | - O | - | - O | X | - O | X | - O | X | - O | X | - O | X | -
- | - | - - | - | - - | - | - - | - | O - | - | O O | - | O X | - | O
Su LaunchPad abbiamo creato le
Scenario 3 pagine del progetto e della
X | - | - X | - | - X | - | - X | - | X X | O | X X | O | X X | O | X squadra Full Circle. L'idea è quella
- | - | - - | O | - - | O | - - | O | - - | O | - - | O | - - | O | X che i nonscrittori possono
- | - | - - | - | - - | - | X O | - | X O | - | X O | - | X O | - | X
collegarsi alla pagina, fare clic su
Scenario 4 "Answers" in alto e lasciare idee
X | - | - X | - | - X | - | - X | - | - X | - | - X | - | X X | O | X per articoli, ma vi prego siate
- | - | - - | O | - - | O | O X | O | O X | O | O X | O | O X | O | O specifici! Non inserite solo
- | - | - - | - | - - | - | X - | - | X O | - | X O | - | X O | - | X
"articolo sui server" ma indicate
Scenario 5 anche cosa il server dovrebbe fare!
X | - | - X | - | - X | - | - X | - | - X | - | - X | - | - X | - | X
- | - | - - | O | - - | O | X - | O | X X | O | X X | O | X X | O | X I lettori che volessero scrivere un
- | - | - - | - | - - | - | - - | - | O - | - | O O | - | O O | - | O
articolo ma sono a corto di idee,
Scenario 6 possono registrarsi alla pagina del
- | - | - - | - | - - | - | - - | - | - - | - | X O | - | X O | - | X gruppo Full Circle quindi auto0
X | - | - X | O | - X | O | - X | O | - X | O | - X | O | - X | O | - assegnarsi gli articoli proposti e
- | - | - - | - | - - | X | - O | X | - O | X | - O | X | - O | X | 0
iniziare a scrivere! Chiediamo che
se non è possibile scrivere
l'articolo nel giro di alcune
settimane (un
mese circa) la richiesta venga
riaperta per permettere a
qualcun'altro di adottarla.
Greg Walters è proprietario della
RainyDay Solution, LLC, una società 0 Pagina del progetto per le idee:
di consulenza in Aurora, Colorado, e https://launchpad.net/fullcircle
programma dal 1972. Gli piace 0 Pagina per il gruppo d'autori:
cucinare, fare escursioni, la musica e
https://launchpad.net/~fullcircle
trascorrere il tempo in famiglia.

full circle magazine n. 45 8 lnglce ^


HOW0TO
Scritto da Greg Walters
Programmare in Python 0 Parte 20

B
entornati. Questa volta Yedrete comparire da qualche
# simple.py
torneremo a occuparci di parte sul desktop una semplice import pygtk
GUI ma utilizzando la finestra. Sul mio compare pygtk.require('2.0')
libreria pyGTN. Per il nell'angolo superiore sinistro. Per import gtk
momento non useremo un designer terminare il programma, dovete
class Simple:
di GUI, ma ricorreremo solo alla premere Ctrl+C nel terminale. def __init__(self):
libreria. Perchä? Non abbiamo aggiunto il self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
codice per distruggere e quindi self.window.show()
terminare l'applicazione. Questo lo def main(self):
Utilizzate Synaptic per installare
gtk.main()
python0gtk2, python0gtk20tutorial e andiamo a fare ora. Aggiungete la if __name__ == "__main__":
python0gtk20doc. seguente riga prima di simple = Simple()
self.window.show()... simple.main()
Iniziamo subito con il primo
programma che usa pyGTN, in alto a self.window.connect("delete_e l'evento delete a una routine di self.window.set_position(gtk.
vent", self.delete_event) WIN_POS_CENTER)
destra. servizio, in questo caso
self.delete_event. Ritornando
Quindi, dopo la chiamata Come potete ben immaginare,
Per un po' ci concentremo su del "False" si consente la rimozione
gtk.main(), aggiungete la seguente l'istruzione posiziona la finestra al
codice semplice. La riga 3 contiene della finestra dalla memoria di
funzione... centro dello schermo. Salvate
un nuovo comando. sistema.
"pygtk.require('2.0')" significa che il l'applicazione come "simple3.py"
def delete_event(self, ed eseguitela.
programma verrà eseguito solo se il widget, event, data=None): Ora non so voi ma io preferisco
modulo pygtk installato è, come gtk.main_quit() che le applicazioni si aprano al
minimo, alla versione 2.0. Nella return False centro dello schermo, non in una Ora è molto meglio, ma non è
routine __init__ assegniamo una posizione a caso, o in un angolo granchä. Allora aggiungiamo un
finestra alla variabile self.window Salvate la vostra applicazione dove potrebbe essere nascosta da widget. Se ricordate i YECCHI
(riga 8) e quindi la mostriamo (riga come "simple2.py" e, ancora una qualcos'altro. Modifichiamo il articoli su Boa Constructor, i widget
9). Ricordate che la funzione volta, eseguitela dal terminale. Ora, codice di conseguenza. Tutto quello non sono altro che controlli
__init__ è eseguita non appena la quando cliccate su "[" nella barra che dobbiamo fare è aggiungere la predefiniti che possiamo
classe è istanziata (riga 13). Salvate del titolo, l'applicazione terminerà. riga seguente prima di aggiungere alla nostra finestra per
il codice come "simple1.py". Cosa è accaduto, quindi? La prima self.window.connect nella funzione fare delle cose. Uno dei controlli
riga che abbiamo aggiunto __init__: più semplici da aggiungere è un
Eseguitelo in un terminale. (self.window.connect...) connette pulsante. Aggiungeremo il codice

full circle magazine n. 46 7 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 20
seguente subito dopo print "Button 1 clicked" nostri controlli. Dovremmo farlo
self.window.connect nella routine anche se abbiamo un solo widget. Proposte e Autori
gtk.main_quit()
__init__: Nel prossimo esempio
aggiungeremo un HBox (un box Cercansi
self.button = Come potete vedere, la routine
orizzontale) per racchiudere il
gtk.Button("Close Me") non fa molto. Mostra nel terminale
nostro pulsante e aggiungerne un
self.button.connect("clicked" "Button 1 clicked" e quindi richiama
,self.btn1Clicked,None) altro. Se avessimo voluto un
la funzione gtk.main_quit(). Questa
contenitore verticale avremmo
self.window.add(self.button) chiuderà la finestra e terminerà Su LaunchPad abbiamo creato le
usato YBox.
l'applicazione, come se aveste fatto pagine del progetto e della
self.button.show() clic su "[" sulla barra del titolo. squadra Full Circle. L'idea è quella
Per iniziare, usiamo simple4.py
Ancora, salvate il tutto come che i nonscrittori possono
come base. Eliminate tutto tra le
La prima riga definisce il "simple4.py" ed eseguitelo in un collegarsi alla pagina, fare clic su
righe self.window.connect(...) e
pulsante e il relativo testo. La terminale. Yedrete una finestra "Answers" in alto e lasciare idee
self.window.show(). Qui
seconda è la connessione all'evento centrata con un pulsante con su per articoli, ma vi prego siate
aggiungeremo le nuove righe. Il
click. La terza aggiunge il pulsante scritto "Close me". Fate click e specifici! Non inserite solo
codice per HBox e il primo pulsante
alla finestra mentre la quarta riga lo l'applicazione si chiuderà, come "articolo sui server" ma indicate
è...
mostra sulla superficie della voluto. Notate, comunque, che la anche cosa il server dovrebbe fare!
finestra. Osservando finestra è molto più piccola che in self.box1 = gtk.HBox(False,0)
self.button.connect noterete la simple3.py. La potete I lettori che volessero scrivere un
presenza di tre argomenti. Il primo ridimensionare ma questo farà self.window.add(self.box1) articolo ma sono a corto di idee,
è l'evento a cui ci connettiamo, il ingrandire anche il pulsante. possono registrarsi alla pagina del
self.button =
secondo è la funzione eseguita Perchä? Semplicemente perchä gruppo Full Circle quindi auto0
gtk.Button("Button 1")
quando l'evento si verifica, in abbiamo inserito un pulsante nella assegnarsi gli articoli proposti e
questo caso "self.btn1Clicked" e il finestra la quale si ridimensiona per self.button.connect("clicked" iniziare a scrivere! Chiediamo che
terzo è l'argomento (se esiste) che adeguarsi al contenuto. ,self.btn1Clicked,None)
se non è possibile scrivere
sarà passato alla funzione appena l'articolo nel giro di alcune
self.box1.pack_start(self.but
definita. Abbiamo in una certa misura ton,True,True,0) settimane (un
violato le regole di mese circa) la richiesta venga
A seguire, dobbiamo creare la programmazione di GUI inserendo il self.button.show()
riaperta per permettere a
funzione self.btn1Clicked. pulsante direttamente nella qualcun'altro di adottarla.
Inseritela dopo self.delete_event: finestra, senza usare un Analizziamolo un po' alla volta.
0 Pagina del progetto per le idee:
contenitore. Dovreste ricordare che Abbiamo un HBox, chiamato
https://launchpad.net/fullcircle
def negli articoli riguardanti Boa self.box1. I parametri passati sono
btn1Clicked(self,widget,data= 0 Pagina per il gruppo d'autori:
Contructor usammo box homogeneous (True o False) e un
None): https://launchpad.net/~fullcircle
ridimensionatori (contenitori) per i valore per lo spazio:

full circle magazine n. 46 8 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 20
L'argomento expand ci permette di commentate la riga: parametro fill su False. Rieseguite e
HBox = scegliere se il controllo dovrà noterete che i pulsanti ancora
gtk.HBox(homogeneous=False,sp riempire lo spazio extra nel box gtk.main_quit() manterranno la larghezza iniziale
acing=0)
(True) o se il box dovrà restringersi ma questa volta lo spazio bianco
per adattarsi al widget (False). Yogliamo che entrambi i sarà distribuito a destra e a sinistra,
Il parametro homogeneous pulsanti stampino il rispettivo
L'argomento fill ha effetto solo se ridimensionando la finestra.
controlla se ciascun widget nel box "Button [ clicked" senza chiudere
l'argomento expand è True. Per Ricordate che il parametro fill non
ha la stessa dimensione (larghezza la finestra.
finire mostriamo il pulsante. Segue fa nulla se expand è impostato su
nel caso di un HBox e altezza nel
il codice per il secondo pulsante: False.
caso di un YBox). In questo caso Salvate come "simple4a.py".
passiamo false e un valore spazio di self.button2 = Eseguitelo nel terminale. Yedrete Un altro modo per organizzare i
0. A seguire aggiungiamo il box alla gtk.Button("Button 2") una finestra centrata con due widget è tramite l'uso di una
finestra. Quindi creiamo il pulsante pulsanti (giusto ai bordi della
self.button2.connect("clicked tabella. Molte volte, se quello che
come prima e colleghiamo l'evento finestra) etichettati "Button 1" e
",self.btn2Clicked,None) abbiamo puí essere disposto
click alla nostra funzione. "Button 2". Fate clic su ciascuno e mediante una struttura a griglia
self.box1.pack_start(self.but vedrete che risponderanno
allora la tabella è la scelta migliore
Ora arriviamo ad un nuovo ton2,True,True,0)
propriamente all'evento click come (e più semplice). Immaginate la
comando. self.box1.pack_start è discusso. Ora, prima di chiudere la
self.button2.show() tabella come una griglia di un
usato per aggiungere il pulsante al finestra, ridimensionatela foglio di calcolo con righe e
contenitore (HBox). Usiamo questo self.box1.show() (trascinate l'angolo in basso a colonne contenenti widget. Ciascun
invece di self.window.add per i destra) e noterete che i pulsanti si widget puí occupare una o più
widget che vogliamo includere nel Potete osservare come il codice allargano e restringono seguendo il celle, come richiesto dalla vostra
contenitore. Il comando (come sia molto simile al precedente. ridimensionamento della finestra. applicazione. Probabilmente il
sopra) è... L'ultima riga mostra il box. Per capire il parametro expand, diagramma seguente aiuta a
cambiate il codice di entrambe le visualizzare le possibilità. Ecco una
box.pack_start(widget,expand= Ora dobbiamo aggiungere la
True, fill=True, padding=0) righe self.box1.pack_start da True a griglia 2x2:
funzione self.btn2Clicked. Dopo False. Riavviate il programma e
self.btn1Clicked inserite il seguente osservate cosa accade. Questa 0 1 2
Ha i seguenti parametri. Prima il
codice... volta, la finestra all'inizio sembra la 0+-----------+-----------+
widget, quindi expand (True or | | |
False), quindi fill (True or False) e stessa ma quando la
def 1+-----------+-----------+
un valore per il padding. Per i ridimensionerete i pulsanti | | |
btn2Clicked(self,widget,data=
contenitori lo spacing rappresenta None): manterranno la dimensione iniziale 2+-----------+-----------+
la quantità di spazio tra i widget con conseguente spazio vuoto a
print "Button 2 clicked" destra allargando la finestra. Nella prima riga inseriremo due
mentre il padding si applica sul lato
destro/sinistro del widget. Proseguiamo ripristinando a True il pulsanti, uno in ciascuna colonna.
e in self.btn1Clicked valore di expand e impostiamo il Nella seconda riga inseriremo un
full circle magazine n. 46 9 lnglce ^
PROGRAMMARE IN PYTHON 0 PARTE 20
pulsante che occuperà entrambe le ,ypadding=0) 20)
colonne. Come questo... button1.show()
self.window.set_size_request(
Gli unici parametri richiesti sono 250, 100)
0 1 2 i primi 5. Quindi per inserire un Ora il pulsante numero 2...
0+-----------+-----------+ pulsante nella riga 0, colonna 0 self.window.connect("delete_e
| Button 1 | Button 2 | vent", self.delete_event) button2 = gtk.Button("Button
1+-----------+-----------+ potremmo usare la seguente 2")
| Button 3 | istruzione...
2+-----------+-----------+ Ci sono alcune cose da chiarire button2.connect("clicked",sel
table.attach(buttonx,0,1,0,1) prima di procedere. La riga 9 f.callback,"button 2")
Per impostare una tabella, imposta il titolo della finestra a
table.attach(button2,1,2,0,1)
creiamo un oggetto table e lo Se avessimo voluto inserirlo "Table Test 1". Usiamo la chiamata
aggiungiamo alla finestra. La nella riga 0, colonna 1 (l'indice inizia "set_border_width" per dare un button2.show()
chiamata per creare la tabella è... da 0) come il pulsante 2 di prima, la bordo di 20px intorno l'intera
chiamata sarebbe stata... finestra prima di posizionare ogni Quasi tutto come per il primo
Table = altro widget. Quindi forziamo la pulsante, ma fate attenzione al
gtk.Table(rows=1,columns=1,ho table.attach(buttonx,1,2,0,1) dimensione della finestra a
mogeneous=True) cambiamento della chiamata
250x100 pixel usando la funzione table.attach. Notate anche che la
Speriamo che questo sia chiaro, set_size_request. A ancora senso? funzione usata per gestire l'evento
Se la variabile homogeneous è in un certo qual modo. Iniziamo con Ora creiamo la tabella e è chiamata "self.callback", ed è la
uguale a True, la dimensione della il codice vero e proprio e capirete l'aggiungiamo alla finestra... stessa per entrambi i pulsanti. Per
tabella sarà quella del widget più meglio. Prima la parte in comune...
grande della tabella stessa. Se ora va bene. Capirete cosa stiamo
table = gtk.Table(2, 2, True)
impostato a False, la dimensione # Create a 2x2 grid
facendo a breve.
# table1.py
sarà determinata dal widget meno import pygtk
alto della stessa riga e da quello più pygtk.require('2.0') self.window.add(table) Ora il terzo pulsante, Sarà il
import gtk nostro "Chiudi":
largo nelle sua colonna. Quindi class Table:
creiamo un widget (come il Proseguiamo creando il nostro
def __init__(self):
primo pulsante, lo connettiamo con button3 = gtk.Button("Quit")
pulsante visto prima) e lo inseriamo
nella tabella nella riga/colonna self.window = l'evento, lo inseriamo nella tabella
button3.connect("clicked",sel
gtk.Window(gtk.WINDOW_TOPLEVE e lo mostriamo...
appropriata. La chiamata è come f.ExitApp,"button 3")
L)
segue...
button1 = gtk.Button("Button table.attach(button3,0,2,1,2)
self.window.set_position(gtk.
1")
table.attach(widget,left WIN_POS_CENTER)
button3.show()
point,right point,top button1.connect("clicked",sel
point,bottom self.window.set_title("Table
f.callback,"button 1")
point,xoptions=EXPAND|FILL,yo Test 1") Per finire, mostriamo la tabella
ptions=EXPAND|FILL,xpadding=0 table.attach(button1,0,1,0,1) e la finestra. Anche qui ricorriamo
self.window.set_border_width(
full circle magazine n. 46 10 lnglce ^
PROGRAMMARE IN PYTHON 0 PARTE 20
alle funzioni main e delete usate terminale. Sono sicuro che ne appropriato per box o tabelle).
precedentemente: capirete l'utilità quando combinato • Mostrare i widget.
a una struttura IF | ELIF | ELSE. • Mostrare il box o la tabella.
table.show() • Mostrare la finestra.
Per finire, dobbiamo definire la
self.window.show()
funzione "ExitApp" per quando si fa Ora abbiamo molti strumenti e
def main(self): clic sul pulsante "Quit"... conoscenze per procedere
ulteriormente. Tutto il codice è
gtk.main() def ExitApp(self, widget,
def delete_event(self,widget,
reperibile su Pastebin:
event, data=None):
event, data=None): http://fullcirclemagazine.pastebin.c
print "Quit button was om/wnzRs[n9. Ci vediamo la
gtk.main_quit() pressed" prossima volta.
return False gtk.main_quit()
Full Circle Podcast
Ora la parte divertente. Sia per il Ed ora il codice main finale...
pulsante 1 che per il 2 abbiamo Nell'episodio n. 15: Brainstorm, FUD
if __name__ == "__main__":
impostato quale funzione di e Media Player
gestione dell'evento "self.callback". table = Table()
Ecco il suo codice. * Recensione: numero 44 di FCM.
table.main() * Notizie: Brainstorm ideas, voti nel
def Software Centre, Fuduntu, Unity,
callback(self,widget,data=Non Combiniamo tutto questo
e): Android e molto altro!
codice in una singola applicazione * Giochi: Humble Indie Bundle 2,
print "%s was pressed" chiamata "table1.py". Eseguitela Mass Effect, FreeCiv e Dropbox.
%data nel terminale.
Dimensioni dei file:
Quello che accade è che quando Per riepilogare, quando si voglia OGG: 46.9Mb
l'utente fa clic sul pulsante, viene usare pyGTN per creare un mp3: 40.4Mb
generato l'evento click e viene programma con GUI, i passi da
inviato il dato fornito alla creazione seguire sono... Durata: 1hr 24min 34secondi
della connessione. Per il pulsante 1 Greg Walters è proprietario della
RainyDay Solution, LLC, una società
Pubblicato il: 13 gennaio 2011
il dato inviato è "button 1" e per il • Creare la finestra.
di consulenza in Aurora, Colorado, e
pulsante 2 è "button 2". Tutto • Creare HBox, YBox o Table per programma dal 1972. Gli piace http://fullcirclemagazine.org/
quello che facciamo è stampare contenere i widget. cucinare, fare escursioni, la musica e
"button x was pressed" nel • Inserire i widget (con il codice trascorrere il tempo in famiglia.

full circle magazine n. 46 11 lnglce ^


HOW0TO
Scritto da Greg Walters
Programmare in Python 0 parte 21

S
e mi state seguendo da
tempo, dovreste ricordare le
lezioni 5 e 6. Allora parlammo
di Boa Constructor e del suo
utilizzo per realizzare applicazioni
dotate di interfaccia grafica. Bene,
questa volta impareremo a usare
Glade. Differente, ma simile. Lo potete
installare con Ubuntu Software Center:
cercate glade ed installate Costruttore
di interfacce utente GTN+ 2.

Giusto per la cronaca, l'applicazione


di oggi sarà trattata in più lezioni. Il fine
ultimo sarà realizzare un generatore di
playlist per i nostri mp3 ed altri file Proprietà e Ispettore.
multimediali. Questa parte del tutorial
si focalizzerà sull'interfaccia. La Nella tavolozza, cercate il gruppo
prossima volta ci occuperemo del "Livelli principali" e fate clic sul primo proprietà cercate il menù a discesa destroy fate clic sul menù a discesa
codice che terrà insieme le varie parti. strumento (posizionando il mouse Posizione finestra e selezionate della colonna Gestore e selezionate
comparirà la scritta "Finestra"). Centrato. Selezionate il checkbox "on_MainZindow_destroy". Questo
Iniziamo col disegnare la nostra Otterremo una "lavagna" vuota con cui Larghezza predefinita e impostate il creerà un evento che occorrerà quando
applicazione. Una volta avviato Glade, lavoreremo. valore a 650. Fate lo stesso con Altezza l'utente farà clic sulla "[" della barra
si aprirà la finestra delle preferenze predefinita ma immettendo 350. Fate del titolo. Un avviso... Dopo aver
(sopra). Selezionate Libglade e Notate che nell'Ispettore comparirà clic, quindi, sulla scheda Comuni e impostato l'evento destroy, fate clic
"all'interno dei livelli principali", quindi window1 sotto la sezione Zidgets. Ora scorrete fino alla voce "Yisibile". ovunque sopra o sotto per rendere
fate clic su Chiudi. Ci sarà così mostrata spostatevi nelle proprietà, cambiate il ASSICURATEYI CHE SIA SELEZIONATO effettivi i cambiamenti. Sembra si tratti
la finestra principale. nome da window1 a MainZindow e "SÌ", altrimenti la vostra finestra non di un bug di Glade. Ancora, salvate il
impostate il Titolo della finestra a sarà visibile. Per finire, selezionate la progetto.
Diamole un'occhiata (a destra). A "Playlist Maker v1.0". Salvate il tutto scheda Segnali, scorrete alla sezione
sinistra c'è la tavolozza, in mezzo l'area come "PlaylistMaker.glade". Prima di GtkObject e fate clic sulla freccia che Proprio come allora, dobbiamo
del designer e a destra le aree proseguire, nella scheda Generale delle punta a destra. In corrispondenza di inserire i nostri widget all'interno di

full circle magazine n. 47 9 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 21
vbox e hbox. Questa è la cosa più (seconda icona da sinistra nella quinta scorrimento. Comparirà una finestra in alto, giusto sotto la barra del titolo.
difficile da ricordare quando si riga nella mia finestra) e fate clic sulla cui scegliere il Modello TreeYiew da Conterrà vari pulsanti che ci
programmano GUI. Andremo a inserire seconda cella della casella verticale. usare. Per ora semplicemente fate clic permetteranno di eseguire la maggior
un contenitore verticale quindi nella Proseguiamo inserendo due Caselle sul pulsante "ON". Lo imposteremo in parte delle operazioni. Useremo undici
tavolozza, nella sezione Contenitori, orizzontali, una per ciascuna delle due seguito. pulsanti e, da sinistra a destra, sono...
selezionate Casella verticale (seconda celle seguenti. Ciascuna dovrà
icona da sinistra nella riga superiore) e contenere tre elementi. Per finire, Ora dobbiamo concentrarci per un Aggiungi, Elimina, Pulisci lista, un
fate clic nella finestra vuota del aggiungete una Barra di stato nella momento sulla Finestra di scorrimento. Separatore, Sposta all'inizio, Sposta su,
designer. Comparirà una finestra con cella in basso. La trovate verso la fine Fate clic su essa nell'ispettore. Scorrete Sposta giù, Sposta alla fine, un altro
cui dovremo scegliere il numero di della sezione Controllo e la scheda Generale fino alla voce Separatore, Informazioni e Esci
elementi desiderati. Il valore visualizzazione della tavolozza. Ora il "Politica barra scorrimento
predefinito è tre, ma noi abbiamo vostro designer dovrebbe assomigliare orizzontale". Cambiare il valore in Nell'ispettore fate clic su "toolbar1"
bisogno di 5 elementi che serviranno, in all'immagine in basso. 'Sempre' e fate lo stesso per Politica per selezionarlo. Nella parte superiore
ordine, per la barra strumenti, una lista barra scorrimento verticale. Salvate di Glade dovrebbe esserci qualcosa che
ad albero, due sezioni per etichette, Ultimo, ma non meno importante: ancora. somiglia a una matita. Fate clic su essa.
pulsanti e campi di testo, e, per finire, aggiungete una Yista albero dalla Comparirà l'Editor della barra
una barra di stato. sezione Controllo e visualizzazione Ok, concentriamoci ora sulla barra strumenti. Fate clic sulla scheda
della tavolozza nel widget Finestra di strumenti. Quest'area sarà quella più in Gerarchia, vedrete qualcosa di simile a
Possiamo cominciare ad aggiungere questo:
i widget. Per iniziare, aggiungiamo una
barra degli strumenti dalla tavolozza. È
(nella mia finestra) la quarta icona della
seconda riga della sezione Contenitori.
Fate clic sulla cella più in alto della
nostra casella verticale. Noteremo che
la cella si rimpicciolirà fino a quasi
scomparire. Non preoccupatevi, la
recupereremo a breve.

A seguire, dovremo aggiungere


nella seconda cella una Finestra di Aggiungeremo tutti i pulsanti della
scorrimento che conterrà la lista ad barra da qui. I passi sono:
albero liberamente scorrevole. Quindi, • Fare clic sul pulsante Aggiungi
cercate Finestra di scorrimento nella • Cambiare il Nome del Pulsante
sezione Contenitori della tavolozza • Modificarne l'etichetta

full circle magazine n. 47 10 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 21
• Selezionare un'immagine chiamandoli "tbtnMoveToTop", ciascuna (da destra a sinistra) l'attributo Espandere della scheda
"tbtnMoveUp", "tbtnMoveDown", un'etichetta, un campo di testo ed un Posizionamento va impostato su "No".
Ripeteremo la procedura per tutti "tbtnMoveToBottom", "Sep2", pulsante. Nella tavolozza, selezionate il Spostatevi sulla scheda Generale e
gli undici widget. Quindi, fate clic su "tbtnAbout" e "tbtnQuit". Sono sicuro widget Etichetta e inseritelo nella cella come Nome inserite btnGetFolder.
Aggiungi, nel campo Nome inserite che troverete le icone corrette. Una a sinistra. Poi inserite il widget Notate che, visto che non si tratta di un
"tbtnAdd". Scorrete in basso fino alla volta finito, potete chiudere la finestra Inserimento testo nella cella centrale e pulsante della barra strumenti,
sezione Modifica etichetta e inserite delle Gerarchie [ndt: a dire il vero è la il pulsante in quella a destra. Ripetete abbiamo omesso la 't' iniziale. Scorrete
"Aggiungi" in corrispondenza di finestra Editor barra strumenti, la procedura per la seconda casella alla voce Etichetta e inserite "Folder...".
Etichetta, quindi poco più in basso, Gerarchia è una sua scheda] e salvare il orizzontale. Quindi fate clic sulla scheda Segnali e
sotto a Modifica immagine, in lavoro. Dovreste avere qualcosa che impostate l'evento GtkButton/clicked
corrispondenza di ID dell'oggetto nello somiglia all'immagine in basso. Dobbiamo ora definire le proprietà su "on_btnGetFolder_clicked". Prima di
stock, usate il menù a discesa e dei controlli appena inseriti. impostare le proprietà degli elementi
selezionate "Aggiungi". Questo Ora dobbiamo impostare i gestori Nell'ispettore, selezionate label1 sotto della successiva casella orizzontale,
conclude il nostro pulsante Aggiungi. degli eventi per i pulsanti creati. hbox1. Nell'area Proprietà, selezionate dobbiamo fare ancora una cosa.
Lo abbiamo chiamato "tbtnAdd" così Nell'ispettore, selezionate il widget la scheda Generale, scorrete fino a Selezionate hbox1 nell'ispettore e
potremo riferirci ad esso in seguito nel tbtnAdd. Questa operazione dovrebbe "Modifica aspetto etichetta" e nella nella scheda Posizionamento
codice. "tbtn" è l'abbreviazione di evidenziare sia la voce nell'ispettore voce Etichetta inserite "Path to save impostate Espandere su "No". Questo
'Toolbar Button'. In questo modo è più che il pulsante stesso. Tornate nell'area file:". Quindi spostatevi nella scheda per far sì che la casella occupi meno
semplice da trovare nel codice, oltre a delle proprietà, selezionate la scheda Posizionamento e impostate spazio. Per finire, impostate il nome
essere auto0documentante. Segnali ed espandete GtkToolButton Espandere su "No". Dovreste ricordare del widget Inserimento testo su
per rivelare l'evento clicked. Nella il discorso sul posizionamento dalla "txtPath".
Dobbiamo ora aggiungere il resto colonna Gestore, come lezione passata. Impostate il
dei widget alla barra strumenti. precedentemente, selezionate riempimento a 4 per inserire un po' di Ora fate lo stesso per la seconda
Aggiungiamo un altro pulsante per "on_tbtnAdd_clicked" quindi fate clic spazio a destra e sinistra dell'etichetta. casella orizzontale, impostando
Elimina. Questo sarà chiamato (come sopra o sotto per forzare la modifica. Ora selezionate button1 e anche qui Espandere su "No", per l'etichetta
potete ben immaginare) "tbtnDelete". Fate lo stesso per tutti gli altri pulsanti
Ancora, impostate l'etichetta e l'icona. creati, selezionando
A seguire, inserite un altro pulsante "on_tbtnDelete_clicked" e così via.
chiamato "tbtnClearAll" e usate l'icona Ricordate di fare clic all'esterno per
Pulisci. Ora abbiamo bisogno del forzare i cambiamenti e salvate il
Separatore. Fate clic su Aggiungi, come progetto. I separatori non hanno
nome inseriamo "Sep1" e nel menù a bisogno di eventi, quindi ignorateli.
discesa Tipo scegliamo Separatore.
A seguire, dobbiamo popolare le
Aggiungiamo i widget rimanenti caselle orizzontali che conterranno

full circle magazine n. 47 11 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 21
impostate il testo su "Filename:",
Espandere su "No", e Riempimento a 4. <widget class="GtkWindow" id="MainWindow">
<property name="visible">True</property>
Impostate il nome per il pulsante a <property name="title" translatable="yes">Playlist Maker v1.0</property>
"btnSavePlaylist", la sua etichetta a <property name="window_position">center</property>
"Save Playlist File...", la proprietà <property name="default_width">650</property>
Espandere su "No" e impostate <property name="default_height">350</property>
<signal name="destroy" handler="on_MainWindow_destroy"/>
l'evento clicked, quindi impostate il
nome del widget Inserimento testo su fortuna dovrebbe incominciare ad possa terminare correttamente con
"txtFilename". Ancora una volta, Yedrete semplice testo che avere senso. Ora dobbiamo scrivere un l'ultima eccezione.
salvate tutto. descrive la nostra finestra e ciascun po' di codice per vedere all'opera il
widget con le relative proprietà. Per frutto del nostro duro lavoro. Avviate Quindi dobbiamo creare la classe
Ora la nostra finestra dovrebbe esempio, diamo un'occhiata al codice l'editor e iniziamo con questo... che definirà la finestra. La trovate in
assomigliare all'immagine in basso a (sopra) per il widget principale, la alto a destra.
sinistra. finestra stessa. Allora, abbiamo creato i nostri
import molto similmente a quanto Simile a quella creata in
Tutto questo è magnifico, ma cosa Potete vedere che il nome del fatto il mese scorso. Notate che stiamo precedenza. Osservate le ultime due
fa davvero? Non possiamo eseguirlo, widget è "MainZindow", il suo titolo è importando "sys" e "MP3" da righe. Stiamo definendo come nome
poichä non abbiamo nessun codice. "Playlist Maker v1.0", il gestore evento, mutagen.mp3. Abbiamo installato del file glade (self.gladfile) quello
Quello che abbiamo fatto è stato e così via. mutagen durante l'articolo n. 9 quindi creato con Glade. Notate anche che
creare un file [ML chiamato se non è presente nel vostro sistema, non abbiamo inserito il percorso, ma
"playlistmaker.glade". Non fatevi Osserviamo il codice (mostrato in fate riferimento a quel numero. solo il nome del file. Se il file glade
ingannare dall'estensione. È proprio un basso) per un pulsante della barra Mutagen servirà la prossima volta, risiederà in un percorso differente da
file [ML, lo potete verificare aprendolo strumenti. mentre sys è usato affinchä il sistema quello del codice, allora dovremo
con il vostro editor preferito (gedit nel
mio caso) e osservarlo. Con un po' di <child>
<widget class="GtkToolButton" id="tbtnAdd">
<property name="visible">True</property>
<property name="label" translatable="yes">Add</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-add</property>
<signal name="clicked" handler="on_tbtnAdd_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>

full circle magazine n. 47 12 lnglce ^


PROGRAMMARE IN PYTHON 0 PARTE 21
indicarlo. Comunque è più semplice cosa leggermente diversa. Useremo un
tenere tutto insieme. A seguire, dizionario. Un dizionario è come un class PlayListMaker:
def __init__(self):
definiamo la finestra come self.wTree array con la differenza che invece di #=============================================
cui faremo riferimento ogniqualvolta usare un indice, useremo una chiave cui # Window Creation
avremo bisogno di operare su di essa. corrisponderà un valore. Chiave e #=============================================
Stiamo anche dicendo che il file Yalore. Ecco il codice che self.gladefile = "playlistmaker.glade"
self.wTree =
probabilmente lo renderà più gtk.glade.XML(self.gladefile,"MainWindow")
#!/usr/bin/env python comprensibile. Per il momento vi
import sys fornirí solo due eventi (mostrati in
from mutagen.mp3 import MP3 ancora bisogno della
try: basso)... routine principale:
import pygtk
pygtk.require("2.0") Allora, abbiamo due eventi: if __name__ ==
except: "on_MainZindow_destroy" e "__main__":
pass plm =
try: "on_tbtnQuit_clicked" sono le chiavi
PlayListMaker()
import gtk del nostro dizionario. Il valore è gtk.main()
import gtk.glade "gtk.main_quit" per entrambe.
except: Ogniqualvolta dalla GUI viene
sys.exit(1) Salvate il file come
richiamato l'evento, il sistema usa "playlistmaker.py". Ora
l'evento per trovare la chiave nel potete eseguirlo
utilizzato è di tipo [ML e che la finestra nostro dizionario e quindi sa quale (mostrato in alto a destra).
userà l'elemento chiamato funzione chiamare, dal corrispondente Sorgente python:
"MainZindow". Potete avere più valore. Non ci resta che connettere il http://fullcirclemagazine.pastebin.com
Al momento non fa molto oltre che
finestre definite in un singolo file dizionario al gestore del segnall della /wbfDmmBh
aprirsi e chiudersi correttamente. Il
glade. Di più a riguardo, un'altra volta. finestra. Lo facciamo con la seguente resto sarà oggetto del prossimo
riga di codice. articolo. Solo per stuzzicarvi l'appetito,
Ora dobbiamo occuparci degli discuteremo di come usare Yiste
eventi. Il mese scorso abbiamo usato self.wTree.signal_autoconnect
(dict) albero, Finestre dialogo e
button.connect o window.connect per aggiungeremo molto codice. Quindi
far riferimento alle funzioni di gestione sintonizzatevi alla prossima volta.
Abbiamo quasi finito. Abbiamo
degli eventi. Questa volta faremo una
File glade: Greg Walters è il proprietario della
#=================================================== RainyDay Solutions, LLC, una società
http://fullcirclemagazine.pastebin.com di consulenza in Aurora, Colorado e
# Create Event Handlers
#=================================================== /\M6U0Ee3 programma dal 1972. Ama cucinare,
dict = {"on_MainWindow_destroy": gtk.main_quit, fare escursioni, ascoltare musica e
"on_tbtnQuit_clicked": gtk.main_quit} passare il tempo con la sua famiglia.

full circle magazine n. 47 13 lnglce ^

Potrebbero piacerti anche