Copy Link
Add to Bookmark
Report
TCL/TK - parte I
@//\\//\\//\\//\\//\\@
{| |}
--{ | -== Tcl/tk ==- | }--
{| (parte I) |}
@//\\//\\//\\//\\//\\@
BAK‹NIN
bakunin@meganmail.com
Immaginate un programma patch di DOS, immaginate la compretezza del linguaggio C,
immaginate la grafica di Windows o di Linux con KDE e GNOME, immaginate tutto ciÚ
come creabile attraverso un linguaggio semplice, gratis, e funzionale...
No! Non Ë un sogno. Tutto ciÚ esiste e si chiama TCL/TK! Un nuovo (pi˘ o meno)
linguaggio che in previssimo tempo conquister‡ presto anche voi. Tutto ciÚ grazie ad
una semplicit‡ sfrenatamente sagerata...
Ovviamente questo non puÚ essere della Microsoft, ed infatti non lo Ë. Se quindi non
girate sotto LINUX, beh... ci risentiamo fra un po' di anni quando Billy e il suo
Windozzo sar‡ solo un brutto ricordo!!! Non Ë detto perÚ! Probabilmente con un po'
di ricerca troverete la versione per Windows. Esiste, ne sono sicuro, ma non so
dove... CERCATE, cercate e poi DITEMI!
Se comunque girate sotto Linux (e se non lo fate leggete e convincetevi a
cambiare idea!) conoscete quei simpatici programmini detti scripts che non sono
altro che comandi in sequenza come per il DOS. Come per il DOS?!? Non proprio perchË
questi sono veri e propri programmi! Hanno una struttura compressa, ruotano su vari
linguaggi, sono veloci e affidabili. Pensate che questi scripts funzionano (se
scritti in PERL, [che prima o poi vi spiegherÚ...] anche su internet...). Se li
conoscete preparatevi a vederli come non li avete mai visti prima...
Se pensate a Linux come un ambiente brutto e oscuro che si basa su shell (come
quelle che sono su internet...) non avete quasi per nulla capito! Linux funziona
anche in ambiente grafico a 32 bit puri come (e probabilmente meglio) Windows e
proprio qui ora creeremo.
"MA COSI' IO CHE HO WINDOZZ E NON HO TROVATO IL TCL/TK MI SPARO?!?" Ebbene NO!
Infatti questo ambiente Ë MultiPiattaforma indi per cui si puÚ usare
indiscriminatamente su Windows e Linux. Quindi no problema... Un giorno magari vi
spiegherÚ come usaro indiscriminatamente ... ma per ora, seguite!
Come forse voi sapete, il "programma" che permette la grafica in Linux si chiama
X-Window (mi raccomando! Senza S finale). X-Window Ë nato circa 10 anni fa quando
nei laboratori del MIT fu creato il primo bozzetto di quel programmino, che, non
vorrei dire ma, WindowsSS ha un po' da invidiare. Infatti, fu creato da 11
produttori di software e hardware a livello mondiale gratuitamente. Nacque quindi
nel 1987 l'X11R1, un consorzio internazionale. Comunque, dopo questa pizzosa
parentesi storica, passiamo ai fatti, cioË:
1 Non Ë un programma, ma un insieme di protocolli, che gestisce im maniera quasi del
tutto autonoma la CPU, la RAM e il disco. Tutto si basa grazie al server TCP/IP. Non
centra assolutamente perÚ con il funzionamento della rete, anzi questi servers sono
solo di architettura.
2 Leggete un po': Mediamente Windozz e similari programmi con la preceduti
dalla parolina "Microsoft" vengono eseguiti dalla CPU da singole postazioni di
lavoro, qui invece tutto Ë rovesciato, nel senso che Ë il server remoto ad eseguire
i programmi, mentre il CPU ha il compito solo di visualizzare. Sta di fatto (per
quelli che non ci stanno gi‡ capendo pi˘ niente) che Ë l'ambiente X che fa le regole
e le gestisce. Rivoluzione del SISTEMA!!!
Altro aspetto dell'ambiente X (che Ë il diminutivo di X-Window), Ë STARTX questo
funge grazie a il file XF86Config che viene impostato dal programma xf86config
(notate che qui le maiuscole e le minuscole sono lettere totalmente diverse). Qui io
lo cito e basta... se volete maggiori info... cercatevele :)
Sappiate comunque che STARTX e file vari sopra citati permettono il corretto
funzionamento dell'ambiente X. Indi per cui sono prima o poi da capire bene. Ma per
ora io vi spiego solo come programmare! Quindi, ancora un po' di pazienza.
Mi dimenticavo di dirvi che ci sono vari ambienti grafici (i pi˘ famosi sono KDE,
GNOME, AfterStep, ecc..) che girano tutti sotto ambiente X.
Ora perÚ vi racconto un po' di storia su questo ambiente, perchË rasenta la
leggenda! Immaginatevi un tipo di nome John Ousterhout, studente alla facolta di
ingegneria informatica (credo, ma comunque sempre informatica era...) che al posto
di comportarsi come gli studenti normali, si trasferisce su Linux, se ne innamora e
prima di finire l'universit‡ scrive il suo PRIMO LINGUAGGIO DI PROGRAMMAZIONE!!!
SÏ! Si Ë scritto un linguaggio, appunto il TCL e poi Ë stato accoppiato al TK,
formando il TCL/TK. Come dire! Un genio. Non ci chiediamo poi perchË la SUN la
prelevato facendone uno dei principali esponenti della mitica produttrice si
software per LINUX. Ovviamente questo Ë successo nel lontano 1989, ma da qui in
avanti, questo programma ha avuto miriadi di modifiche fino ad arrivare alla
versione 8, totalmente gratuita! Sembra che la versione pi˘ stabile sia la TCL/TK
7.6/4.2 ma, io parlerÚ della 8.0 perchË, Ë quella che ho installato e che ritengo
pi˘ semplice e creativa. Soprattutto non vi crediate di riuscire a incriccare il
programma. Non Ë la versione pi˘ stabile, ma prima di far cashare il programma,
altro che questa guida vi serve!
Ho parlato un po' di tutto, e penso che questa introduzione ora deve finire! Quindi
incomincio subito col dirvi:
Credete che vi abbia preso in giro su fatto della semplicit‡? Provate a fare questo:
Aprite un editor qualsiasi e create il file prova.tcl con le seguenti righe di
codice:
--------INIZIO---------
#!/usr/bin/wish
label .msg -text "Ciao MAMMA!!"
button .bye -text "CIAO" -command {exit}
pack .msg .bye
----------FINE---------
Poi uscite e rendete il file eseguibile attraverso il comando:
chmod +x prova.tcl
e poi fatelo partire, ovviamente in ambiente X con il comando:
prova.tcl
e guardatevi lo spettacolo!
Spiegazione a dopo.
-------------------------------
| INDICE: |
-------------------------------
| 1) Installazione |
| 2) Regole |
| 3) Scrivere, commentare, ecc..|
| 4) Variabili e simili |
| 5) Stringhe e simili |
| 6) Cicli |
| 7) Procedure |
| 8) File |
| 9) Esecuzione comandi |
| 10) GRAFICA!!! |
| a) Etichette |
| b) Frame |
| c) Input |
| d) Pulsanti |
| e) Disegni |
| f) PACK |
| g) Listbox |
| h) Eventi |
| 11) Cose carine |
| 12) TCL/TK e internet |
| 13) Creare un database |
-------------------------------
Installazione
Per installare tcl/tk bisogna avere le sorgente. Ma prima d'installare controllare
di averlo non farebbe certo male. Le uniche possibilit‡ che vi impediscono di averlo
Ë avere una versione di LINUX risalente a pi˘ di 2 anni fa. Comunque per installarlo
bisogna avere il codice sorgente. Queste si possono scaricare al sito
http://sunscript.sun.com . Io vi consiglio quelle 8.0. Entrate come untente root ed
eseguire da prompt i seguenti comandi:
tar .zxf nome_dei_file.tar.gz
I file saranno due: tcl8_0p2.tar.gz e tk8_0p2.tar.gz (i nomi potrebbero non
corrispondere!) e quindi bisogna fare l'operazione 2 volte.
Poi entrare nella directory creata e fare:
configure
make
make install
Facciamo gli stessi comandi nella seconda directory creata. Dovrebbero essersi crate
le directory /usr/local/lib le librerie tcl/tk mentre i binari saranno nella
directory /usr/bin.
Ora facciamo:
ln -sf /usr/local/bin/tclsh7.6 /usr/bin/tclsh
ln -sf /usr/local/bin/wish4.2 /usr/bin/wish
Entrate poi nel file /etc/profile o nel file ~/.profile e scrivete:
export TCL_LIBRARY=/usr/local/lib
export TK_LIBRARY=/usr/local/lib
Questi comandi regolano le variabili d'ambiente.
FINE DELL'INSTALLAZIONE...
Regole
Poche ma ferree.
- Incominciamo col dire che in Linux non ci sono estensioni
particolari per il file script, ma se poi vorremmo utilizzare questo programma per
internet Ë necessario che questo venga usato con l'estensione .tcl . Non Ë
necessario ma Ë meglio.
- Il programma non parte se prima non lo si rende eseguibile attraverso il comando:
chmod +x nome_file.tcl
- Io parto dal presupposto che i file necessari (cioË l'interprete dei comandi
tclsh) sia contenuto nella directory /usr/bin/
- "parole varie" Le virgolette servono per far considerare pi˘ parole come una sola.
Questo Ë necessario per i testi o simili.
- Il segno $ e tutte le sue funzioni viene considerato solo se tra parentesi
quadrate. ESEMPIO: [$i + 34] Poi vedremo che non ha senso, ma soltanto dopo...
- Le parentesi graffe {} si usano prevalentemente per le procedure.
- \ si usa per caratteri speciali (come le " che si per renderle visibili bisogna
fare \". Li vedremo pi˘ avanti), ma anche per andare a capo e simili (\n e \r
come in C).
- I commenti si fanno grazie al segno #
Tutto quello che ora faremo sar‡ senza grafica in ambiente X. La grafica sar‡
l'ultima cosa che impareremo a fare. Altrimenti vi manca il bagaglio culturale. E la
cultura Ë potere! Comunque rilassatevi, io questo programma l'ho imparato in circa
una settimana. Voi ci impiegherete circa un mesetto, ma non vi preoccupate!
Scrivere, commentare, ecc...
Incominciamo subito con un esempio:
-----INIZIO---------
#!/usr/bin/tclsh
#Questo Ë un commento, quello sopra \
no. E un comando necessario e intoccabile. \
Come vedete queste ultime righe non sono \
precedute dal solito segno di commento perchË \
grazie al segno che c'Ë in fondo ad ogni riga \
cioË questo: \
io posso continuare a fare commenti.
puts "Ciao mondo"
#Con questo comando scrivo Ciao Mondo sullo schermo \
avrei potuto perÚ anche fare:
puts stdout {Ciao mondo}
#Questo comando Ë uguale a prima.
------FINE-----------
Per non avere il ritorno a capo basta usare l'opzione -nonewline, usato cosÏ:
puts -nonewline "Ciao Mamma"
In questo modo non si andr‡ a capo.
Variabili e simili
Con il TCL (che Ë il programma che impareremo per primo...) non ha bisogno, al
contrario di molti altri programmi, di inizializzare le variabili all'inizio del
programma. Le variabili che si usano di pi˘ sono quelle SCALARI. Queste si usano
perchË non accupano memoria e, appunto, non hanno bisogno di dichiarazioni iniziali.
Per creare una variabile bisogna usare il comando set.
-----INIZIO---------
#!/usr/bin/tclsh
set nome giovanni
puts "Il nome di questo programma e\' $nome"
-----FINE-----------
Come potete vedre questo Ë un programmino che usa la variabile nome per inserire al
suo interno la parola giovanni e poi la stampa. La variabile viene stampata grazie
al comando puts e il $ prima della variabile. Ho usato anche il comando \' per fare
l'apostrofo, perchË questo Ë uno dei comandi che devono essere preceduti da \.
Per fare calcoli bisogna usare il comando expr contenuto tra le parentesi quadrate.
esempio:
set a 5; set b 2
set c [expr 5/2]
puts $c
set d $c
puts [expr 5.0/2]
unset d
Ho fatto un po' di roba inutile! Guardiamo bene:
La prima riga Ë normale, ho semplicemente fatto due righe in una mettendo un ; tra
un comando Ë l'altro. E' infatti uguale:
set a 5
set b 2
e
set a 5; set b 2
Nella senconda ho creato la variabile c contenente la frazione 5/2. Come vedete expr
deve essere contenuto tra parentesi quadrate. Nella terza stampo la variabile $c
(vedrete poi che stampa soltanto 2 come risultato, per ovviare a questo avrei
dovuto mettere al posto che [expr 5/2] il comando [expr 5.0/2]). Non ho messo le ""
perchË Ë una parola sola. Nella quarta riga ho creato la variabile d contenente il
valore di c. Nella quinta Ë stampato la frazione 5/2 ma stavolta ho messo 5.0/2 in
modo che mi facesse vedere anche i numeri dopo la virgila. Nell'ultima riga ho
eliminato la variabile d.
Esiste anche un altro modo per impostare la virgola e in numeri dopo. Questo Ë
ottenibile grazie a questo comando:
set tcl_precision n
ove n sta per il numero di valori che deve inserire dopo la virgola.
Quindi nell'esempio:
set tcl_precision 9
puts [expr 1/3]
il risultato sar‡ 0.333333333 quindi 9 numeri dopo la virgola.
Gli array fanno parte delle variabili e quindi li inserisco qui.
Per creare array si usa il seguente metodo:
set variabile(nome_prima) ciao
set variabile(nome_seconda) addio
set variabile(nome_terza) "come stai?"
Come vedete ho creato un array di variabili di nome variabile e come "sottotitolo",
nome_prima, nome_seconda e nome_terza.
Quindi ricapitolando gli array sono variabili che possono contenere pi˘ dati
all'interno di una stessa variabile. Questo lo fa. Infatti all'interno della
variabile variabile c'Ë ciao, addio e come stai?.
Per richiamare queste basta usare il comando:
puts $variabile(nome_prima)
puts "ed ecco a voi un altro metodo: $variabile(nome_seconda)"
La differenza tra il primo comando e il secondo Ë che il primo funziona con una sola
parola e quindi non si mettono le virgolette. Nel secondo caso ho messo le
virgolette perchË ho inserito il testo.
Per sapere quante variabili puÚ contenere l'array in questione si usa il comando:
puts [array size variabile]
ove array e size sono fissi e variabile Ë il nome dell'array che ci interessa. La
risposta a questo comando sar‡ 3, poichË l'array variabile si divide in 3.
Ora parlerÚ di liste. Le liste sono variabili che contengono deternimati valori e
che io posso leggere e modificare lungo il programma. Il comando per far ciÚ
Ë:
set nome_lista {1 2 3 4 5 6}
Crea una lista di nome nome_lista e contenente i valori 1,2,3,4,5,6. Posso creare
perÚ anche una lista contenente gruppi di valori:
set nome_lista {{1 2 3}{4 5}{6}}
Come vedete ho creato una lista contenente come valore pi˘ blocchi di dati.
I comandi per leggere questi dati sono:
I comandi per leggere e modificare sono:
-----------------------------------------------------------------------
| llenght nome_lista | Mi da il numero di dati inseriti nella lista |
-----------------------------------------------------------------------
| lindex lista indice | Mi da il valore di numero della lista |
| | L'indice puÚ essere un numero da 0 in avanti |
-----------------------------------------------------------------------
| linsert lista indice elemento |Inserisce l'elemento nella lista |
-----------------------------------------------------------------------
| lsort opzioni lista | Ordina una lista in base alle opzioni: |
| | - ascii | logica lessicografica |
| | - integer | in base al numero ascii |
| | | crescente |
| | - increasing | in ordine crescente |
| | - decreasing | in ordine decrescente |
-----------------------------------------------------------------------
Ovviamente per visualizzare qualcosa bisogna usare questo metodo:
puts [lsort -decreasing nome_lista]
cioË usando il comando puts.
Per ricevere un valore, una risposta che deve essere inserita ovviamente all'interno
di una variabile si usa il seguente comando:
set a [gets stdin]
Con questo comando, il programma aspetta che l'utente inserisca un valore. E'
semplice il concetto: creo una variabile (nel mio caso di nome a) e al posto di
inserire un valore imposto che questo sia preso dalla tastiera (gets stdin che Ë un
comando fisso).
Per avere un valore da un utente io posso usare anche la formula:
puts "Dammi un valore: "
gets stdin ciao
AvrÚ cosÏ la variabile ciao contenente il valore.
Mediamente si usa per il comando puts l'opzione -nonewline perchË altrimenti si va a
capo nella richiesta di valore.
Stringhe e simili
Per il linguaggio tcl tutto Ë stringa pure un numero. I numeri diventano tali solo
quando sono preceduti dal comando expr che permette di calcolare. Per gestire le
stringe esiste un comando particolare che Ë:
string opzione argomento
ove opzione ve lo spiego fra un po', e argomento Ë la stinga in questione.
Le opzioni pi˘ comuni sono compare, lenght, match e trim.
Ma pi˘ esattamente queste opzioni sono:
-----------------------------------------------------------------------
| string compare | Confronta due stringe e da la diversit‡ in |
| |ordire altabetico: |
| | -1 se Ë minore la prima, 0 se sono pari |
| | 1 se la prima Ë maggiore |
-----------------------------------------------------------------------
| string lenght | Da il numero di caratteri |
-----------------------------------------------------------------------
| string match | Confronta con un modello la stringa. I valori |
| | di confronto sono uguali a quelli di compare. |
| | Il modello puÚ essere tra questi: |
| | abc* | confronta tutti i caratteri con tutti |
| | abc? | confronta un singolo carattere |
| | \ | per confrontare i caratteri * e ? |
-----------------------------------------------------------------------
| string strim | restituisce la string senza i caratteri |
| | specificati. Se non metto niente mi toglie |
| | gli spazi bianchi, i punti, le tab, ecc... |
-----------------------------------------------------------------------
Un altro esempio inutile:
------INIZIO--------------
#!/usr/bin/tclsh
string compare "abcdefgh" "ilm"
#il risultato sar‡ -1 perchË \
ilm sono lettere dopo abcdefgh
string compare "abcd" "abcd"
#il risultato sar‡ 0
string compare "def" "abc"
#il risultato sar‡ 1
puts [string trim "ciao mamma " .m]
#il risultato sar‡ ciaoaa perchË ho \
tolto tutti gli spazie i punti e e le m.
#in vi ho spiegato i cicli ma sono semplici questi:
set ciao "mamma mia"
if {[string length $ciao]>5} {
puts "Nome lungo"
} else {
puts "Nome corto"
}
#nel nostro caso scrive nome lungo.
--------FINE--------------
Dovete fare incredibilmente attenzione con gli spazi nel ciclo, altrimenti vi dar‡
errori vari. Gli‡! Gli errori sar‡ un argomento che dovrÚ atrattare.
Il comando split serve per sostituire caratteri separatori all'intero di una
stringa:
split stinga caratteri
puts [split "ciao mondo"]
risultato sar‡: ciao mondo
se invece scrivo
puts [split ciao*mondo *]
risultato sar‡: ciao mondo
Cicli
Come ogni programma ci sono i cicli. I primi due sono l'IF e il SWITCH.
Incominciamo col primo, l'IF.
Il funzionamento del comando IF Ë sempre lo stesso di ogni altro linguaggio di
programmazione. Ma Ë particolarmente importante qui i numeri di spazi e
l'ipostazione grafica. Altrimenti non funge!
IF {condizione1} {
corpo1
}
Come potete vedere le parentesi graffe contengolo il corpo e la condizione. La
condizione puÚ essere del tipo: {$a>2}, e qualsiasi altro tipo, ma l'importante Ë
che non compaino spazi tra i vari fattori. E' errore: {$a > 2}. Non devono comparire
spazi!
Tra la parentesi di chiusura della condizione e la prima del corpo ci deve essere
uno spazio, altrimenti errore! Insomma deve essere fatta come nell'esempio qui
sotto:
--------INIZIO-------------
#!/usr/bin/tclsh
puts "il valore di A e\': "
set a [gets stdin]
puts "Il valore di B e\': "
set b [gets stdin]
if {$a==$b} {
puts "A e B sono uguali"
} elseif {$a>$b} {
puts "A e\' maggiore di B"
} else {
puts "A e\' minore di B"
}
--------FINE---------------
Spiegazione: il comando set a [gets stdin] permette di ricevere un valore (ve lo
ricordate?). Poi attraverso un ciclo IF confronto (==) i valori di a e b (ricordo
che a e b sono le variabili mentre $a e $b sono i valori dentro le variabili). Poi
se sono uguali dico... mentre se sono diversi dico ...
Da notare i comandi elseif e else. La differenza Ë che elseif apre gi‡ un ciclo if
partendo da presupposto che il primo non si sia avverato. Else invece non apre
nessun ciclo.
Esiste poi il ciclo con switch che permette il confronto booleano fra due stringhe o
due proposizioni o di una stringa e un modello.
Si usa cosÏ:
switch opzioni stringa modello corpo
oppure
switch opzioni stringa {modello corpo}
Le opzioni possono essere :
-------------------------------------------------------------------------------
| -exact | confronta e da esito positivo solo se la stringa e il modello |
| | sono uguali |
-------------------------------------------------------------------------------
| -glob | si usa in concomitanza con il comando string match che crea |
| | un modello da confrontare poi con la stringa in questione |
-------------------------------------------------------------------------------
| -regex | permette l'uso delle espressioni regolari (ve le spiego...) |
-------------------------------------------------------------------------------
| -- | indica la fine delle opzioni |
-------------------------------------------------------------------------------
Esempio chiarificatore:
---------INIZIO--------------
#!/usr/bin/tclsh
puts "Dammi un valore booleano: "
gets stdin booleano
switch -exact -- $booleano {
1 {puts vero}
yes {puts vero}
true {puts vero}
sÏ {puts vero}
vero {puts vero}
0 {puts falso}
no {puts falso}
false {puts falso}
falso {puts falso}
default {puts "Valore inserito non booleano"}
}
---------FINE----------------
Spiegazione: ho chieso un valore se il primo valore Ë uguale alle parole 1, yes,
true, sÏ o vero allora verr‡ visualizzata la parola vero. Al contrario se inserisco
le parole 0, no falso, false verr‡ stampato la parola faso.
Se inserisco un altro valore verr‡ visualizzato la frase Valore inserito non
booleano.
Da notare il comando default che permette di scrivere qualcosa, o di fare una
determinata operazione, se tutti gli altri confronti falliscono.
Gli altri ciclo sono il FOR, il WHILE e il FOREACH. Incominciamo con il FOR.
La truttura Ë cosÏ:
for {inizializzazione_variabile} {condizione} {incremento} {
...operazioni varie...
}
ESEMPIO:
for {set a 0} {$a<=10} {incr a} {
puts "A vale $a"
}
Questo ciclo stamper‡ questo:
A vale 0
A vale 1
A vale 2
A vale 3
A vale 4
A vale 5
A vale 6
A vale 7
A vale 8
A vale 9
A vale 10
E la spiegazione Ë questa:
for apre il ciclo
{set a 0} crea una variabile a di valore 0
{$a<=10} Imposta che non deve superare il valore di 10
{incr a} La incrementa
{ apre in corpo di operazioni
puts "A vale $a" scrive il valore di $a
} chiude il tutto
CÏÚ si poteva fare anche un ciclo WHILE:
while {condizione} {
...operazioni varie...
}
Che nel nostro caso diventerebbe:
set a 0
while {$a<=10} {
puts "Il valore di A Ë $a"
incr a
}
Abbiamo appena visto il funzionamento di WHILE. Fate attenzione a un comando in
particolare cioË incr a. Questo comando incrementa la variabile a. Se non l'avessi
emsso si sarebbe originato un ciclo, all'infinito.
Ora Ë il momento di FOREACH che si usa prevalentemente con le liste:
foreach variabile lista {
...operazioni varie....
}
foreach a {1 2 3 4 5 6 7 8 9 10} {
puts "Il valore di A Ë $a"
}
Il funzionamento Ë uguale agli altri due. Qui indico i valori che a deve toccare e
poi gli faccio fare una operazione tante volte quante sono i valori nella lista.
Procedure
Anche TCL puÚ essere strutturato in procedure. CiÚ comporta che puÚ avere dei
blocchi di codice (appunto chiamati procedure) che possono essere richiamati
attraverso il comando specifico. L'utilit‡ di ciÚ (lo dico per chi non le ha mai
utilizzate) Ë di allegerire il corpo del programma, di racchiudere parti che
verrebbero fatte funzionare pi˘ volte una volta per tutte senza riscriverle sempre,
e in pi˘ di trovare velocemente gli errori.
nome_procedura {} {
...comandi vari....
}
Tutto ciÚ si fa grazie al comando proc seguito dal nome della procedura. Se
volessimo che la procedura prendesse variabili gi‡ usate e rimpite dal programma per
effettura determinate operazioni, questo di deve fare nel seguente modo:
set a 5
set b 4
proc somma1 {} {
set a 1
set b 9
set somma [expr $a+$b]
puts $somma
}
proc somma2 {} {
global a b
set somma [expr $a+$b]
puts $somma
}
proc somma3 {a b} {
set somma [expr $a+$b]
puts $somma
}
somma1; #risultato 10
somma2; #risultato 9
somma3; #risultato 9
Vediamo un po' cosa fa questo semplice programmino: creo due variabili a e b.
-PRIMA PROCEDURA: somma 2 variabili che si crea lui e che non centrano nulla con le
variabili a e b del programma generale. Il risultato sar‡ 10.
-SECONDA PROCEDURA: somma le due variabili del programma generale poichË riprese dal
comando GLOBAL. Questo comando permette di riprendere le variabili dal programma e
di utilizzarle.
-TERZA PROCEDURA: prende le due variabili e le somma grazie all'inserzione di esse
tra le parentesi graffe.
Vediamo il comando arg:
proc ciao {a b c arg} {
puts $a
puts $b
puts $c
puts $arg
}
prova 1 2 3 4 5 6 7 8
Il risultato sar‡:
1
2
3
4 5 6 7 8
Questo perchË il comando arg stampa tutti i valori dopo quelli che la procedura puÚ
accettare considerandoli un unico valore. Nel nostro caso la procedura ciao poteva
ricevere 1 2 3 rispettivamente dalle variabili a b c il resto no. Quindi arg accetta
il resto ma lo considera unico, quindi sulla stessa riga.
Per modificare un valore di una variabile attraverso una procedura si usa il comando
upvar usato nel seguente modo:
set a 5
proc ciao {} {
upvar a b
set b 9
}
ciao
puts $a; # apparir‡ 9
Questo perchË alla riga 6 ho fatto partire la procedura ciao che cambiava a da 5 a
9.
File
Per aprire un file bisogna usare queste righe di comando:
set idfile [open "./prova.doc" r]
while {[gets $idfile riga] !=-1}{
puts $riga
}
close $idfile
Che spiegati sono: creo una variabile di nome idfile ove apro (open) un file di nome
"prova.doc" in sola lettura (r).
Dopo di che faccio incominciare un ciclo (while) finchË il file non finisce. Poi
stampo ogni singola riga.
Ricordarsi sempre di chiudere il file altrimenti questo non verr‡ salvato con le
modifiche che voi avete fatto (close $idfile)!
Questo Ë la spiegazione. Quindi abbiamo capito che il comando open si utilizza cosÏ:
open "nome file" modo_di_lettura
Il modo di lettura puÚ essere r (read quindi solo lettura), ma anche w (write) nel
seguente esempio ove creo un file di nome prova.txt:
set idfile [open "./prova.txt" w]
puts $idfile "CIAO MAMMA!!!"
close $idfile
Queste due righe aprono un file di nome prova.txt in scrittura e poi ci scrivono
sopra CIAO MAMMA!!!
Ovviamente possiamo aprire i file anche in binario:
set idfile [open "./prova" r]
while {![eof $idfile]} {
set buffer [read $idfile 1024]
...comandi e comandi...
}
close $idfile
Altro importantissimo comando Ë il GLOB che permette di trovare i file con
caratteristiche comuni e di fare operazioni su tutti quanti in contemporanea:
foreach txt [glob *.txt] {
set idfile [open $txt r]
while {[gets $idfile riga] !=-1} {
puts $riga
}
close $idfile
}
Questo caso permette di trovare tutti i file con espensione .txt e di visualizzarli.
Eseguire comandi
Per eseguire comandi del prompt e non, bisogna usare in comando exec:
exec ls
Ma se volessimo visualizzare tutti i file *.txt (cioË tutti quei file che hanno
come estensione txt: MA SE NON SAPETE QUESTO CHE RAZZA DI PROGRAMMATORI SIETE...)
non potete vare cosÏ:
exec ls *.txt; #errore!!!!
Per risolvere questo problema si usano i comandi eval e glob:
eval exec ls [glob *.txt]; #esatto!!!
Questo comando permette di visualizzare i file *.txt.
EX CLARO?
GRAFICA!!!
Incominciamo ora, dopo aver capito il base del TCL, con i comandi base del TK.
Questo linguaggio Ë molto semplice, leggero e grafico, e ha una struttura fissa per
tutti i comandi:
nome_dello_strumento nome_nostro opzioni
Il nome_dello_strumento puÚ essere button (pulsante), label (etichetta), ed altri.
Il nome_nostro Ë il nome che vogliamo dare al nostro pulsante o etichetta, mentre le
opzioni sono cosa far‡ questa etichetta o in generale, strumento.
Incominciamo quindi subito con l'impostare le dimensioni della finestra e i suoi
colori:
-------INIZIO---------
#!/usr/bin/wish
wm title . "CIAO MAMMA!!"
wm resizable . 0 0
. configure -bg white
-------FINE-----------
Spiegazione:
La prima riga come vedete imposta un altro imterprete dei comandi che permette di
visualizzare in grafica.
wm imposta le caratteristiche della pagina e, nella seconda riga in particolare
imposta il titolo della finestra principale "." con il nome di CIAO MAMMA!!
Come, finestra principale? SÏ, perchË la finestra principale Ë chiamata "." mentre i
suoi oggetti sono .ciao .nome_a_caso che dobremmo poi impostare noi. Quindi . Ë il
principale mentre gli oggetti contenuti (che possono essere pulsanti, etichette o
simili) si chiamano .nome . Diverso Ë con i frame poichË questi saranno anch'essi
oggetti e quindi detti: .nome_frame ma dato che essi possono reggere pulsanti,
etichetti, ecc i nomi di questi ultimi saranno .nome_frame.nome_pulsante .
Capito?
Ve lo spiego con un grafico:
.
/\
/ \
/ \
.pulsante .frame
|
|
/ \
/ \
/ \
.frame.pulsante \
.frame.frame2
|
|
|
.frame.frame2.pulsante
Ex claro?
Continuando con la spiegazione:
wm resizable . 0 0 serve ad impostare che le dimensioni della finestra . non possono
essere modificate nÈ in altezza (primo 0) nÈ in larghezza (secondo 0).
. configure -bg white
Configuro che lo sfondo (-bg) della finestra principale (.) deve essere bianco.
Vi consiglio di farvi uno schizzo su carta delle vostre costruzioni altrimenti... La
vedo tesa sul fatto di riuscire a disegnare bene i vostri programmi!
Vi ricordo che per visualizzare i comandi che mettete dovrete usare il comando pack
che perÚ spiegherÚ dopo gli altri. Quindi per ora aspettate...e leggete!
Etichette
Incominciamo con un esempio:
label .nome -text "Ciao!! Come stai?" -bg red
Per fare le etichette si usa il comando label seguito dal nome dell'etichetta e dal
comando text che regola il testo. Dopo di che bisogna regolare il colore dello
sfondo. Se non facciamo questo ultimo comando apparir‡ quello default. Che nel
nostro caso Ë bianco (vedi sopra).
Frame
I frame si fanno attraverso il comando FRAME:
frame .nome_frame -bg colore
I frame dividono la finestra in pi˘ parti. Per mettere nel nostro frame una
etichetta dovremmo fare cosÏ:
frame .nome_finestra.nome .text "Etichetta nel frame!!"
Input
Gli input si creano con il comando Entry:
entry .ciao -textvariable a
Si crea un input cioË quello spazio dove posso scrivere qualcosa, con il nome .ciao.
CiÚ che scriverÚ andr‡ inserito nella variabile a.
L'uso delle variabili lo do per noto poichË Ë lo stesso principio di tcl.
Quindi non batando alla grafica:
-------INIZIO---------
#!/usr/bin/wash
wm title . "CIAO MAMMA!!"
wm resizable . 0 0
. configure -bg white
label .1 -text "Dammi il primo numero: "
entry .2 -textvariable a
label .3 -text "Dammi il secondo numero: "
entry .4 -textvariable b
pack .1 .2 .3 .4
set c [expr $a+$b]
label .5 -text "La somma Ë $c"
pack .5
-------FINE-----------
Non vi chiedete il funzionamento pack perchË ve lo spiegherÚ dopo. Per ora vorrei
farvi notare che le etichette sono 2 e che gli input sono anch'essi 2. Poi sommo le
variabili allo stesso modo in cui facevo con TCL e poi visualizzo.
Pulsanti
I pulsanti si facco cosÏ:
button .nome -text "Il testo sopra il pulsante" -command {opzione}
Il pulsante di nome .nome e con il testo "Il testo sopra il pulsante se cliccato con
il mouse far‡ partire il comando opzione.
Tra le opzioni ci sono in prevalenza 2:
- exit che comporta l'uscita dal programma
- una procedura (le strutture delle procedure le do per note dal TCL"
Esiste, sempre legato ai pulsanti i RADIOBUTTON che sono i pulsantini a rompo.
Si usano come gli altri, solo che non si mette il testo dentro ma fuori e si fa
cosÏ:
radiobutton .nome -text "CiÚ che si vuole."
Disegnare
Per disegnare si usa il comando canvas.
canvas .nome -width numero -height numero -bg colore
ove nome Ë il nome della parte dedicata al disegno, -width regola l'altezza in pixel
della larghezza e height della altezza. Il colore Ë il colore di sfondo che gi‡
conosciamo.
canvas .ciao -width 200 -hieght 200 -bg black
Vi ricordo che non disegnare voi con il mouse ma visualizza l'andatura di un grafico
o simili.
Per cancellare un grafico e scrivero sopra basta fare
.ciao delete all
Canceller‡ tutto sul grafico.
PACK
Il pack permette di visualizzare gli oggetti nel programma. Ne ho parlato per ultimo
perchË ha 200 milioni di opzioni.
Cos'Ë il PACK? Non Ë proprio un visualizzatore Ë un gestore. CioË Ë un "programma"
che riempe automaticamente le opzioni che noi lasciamo vuote o trascuriamo (quando
ci dimentichiamo di mettere il colore di sfondo o ecc..), e si preoccupa di
posizionare correttamente gli oggetti nella grafica.
Esistono 2 gestori. Il placer e il packer. Io uso il secondo prevalentemente perchË
Ë pi˘ completo e permette operazioni che l'altro non permette. Comunque ve li spiego
entrambi.
IL PLACER colloca gli oggetti relativamente al contenitore e in modo eseparato.
Quindi provoca la sovrapposizione di oggetti o simili.
Il funzionamento Ë questo:
place .nome_oggetto -x n -y n
Ove n sono i due numeri che riguardano le ordinate e le ascisse.
Si puÚ usare il comando -anchor per ancorare l'oggetto al bordo:
place .nome -anchor center
Il PACKER
Permette di gestire pi˘ oggetti in comtemporanea. Il suo funzionamento
"intelligente" Ë questo:
1 Sceglie il lato della cavit‡ (posto in cui l'oggetto puÚ essere inserito)
2 Ricava una sezione per l'oggetto (maggiore o no dell'oggetto stesso)
3 PuÚ ingrandire l'oggetto se vogliamo
4 Lo colloca.
Questa Ë la differenza tra il Packer e il placer, cioË valuta la distanza tra
oggetto e oggetto prima di collocare.
Ora beccatevi questa tabellina:
-------------------------------------------------------------------------------
| BORDATURE |
-------------------------------------------------------------------------------
| -padx 2m -pady 1m | Regola la distanza di 2 rispetto ai bordi o ad un |
| | altro oggetto. Padx lateralmente, pady verticalmente |
-------------------------------------------------------------------------------
| -ipadx 2m -ipady 1m | Regola la distanza di 2 rispetto ai bordi o ad un |
| | altro oggetto ma a differenza di quello sopra, allarga|
| | i bordi. |
-------------------------------------------------------------------------------
| -padx 2m -pady 1m \ | Fa per met‡ il primo comando e per met‡ l'altro |
| -ipadx 2m -ipady 1m | |
-------------------------------------------------------------------------------
Ora una per le Saturazioni (cioË l'espanzione dei pulsanti):
-------------------------------------------------------------------------------
| SATURAZIONI |
-------------------------------------------------------------------------------
| -pack .1 .2 -side top | Mette un oggetto sotto l'altro |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left| Mette un oggetto a sinistra l'altro |
-------------------------------------------------------------------------------
| -pack .1 .2 -side \ | Mette un oggetto a destra l'altro |
| right | |
-------------------------------------------------------------------------------
| -pack .1 .2 -side top\| Fa quello sopra e in pi˘ estende i bordi fino al |
| -fill x | consentito dai bordi in orizzontale |
-------------------------------------------------------------------------------
| -pack .1 .2 -side top\| Fa quello sopra e in pi˘ estende i bordi fino al |
| -fill y | consentito dai bordi in verticale |
-------------------------------------------------------------------------------
| -pack .1 .2 -side top\| Ovviamente entrambi |
| -fill y -fill x | |
-------------------------------------------------------------------------------
PS .1 e .2 sono due oggetti a casi. \ Indica (come in TCL) il continuamento dello
stesso codice anche se a capo.
Ora un'altra per le Espansioni. Cosa sono le espansioni? Sono l'algamento della
finestra da una parte:
-------------------------------------------------------------------------------
| ESPANSIONI |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left | Lo conosciamo gi‡. Sar‡ il nostro punto di partenza |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left | Aggiungo al comando di prima un altro pack che regola|
| -pack .3 -side left \ | la visualizzazione del .3 . Poi espando. |
| -expand true | |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left | Uguale a prima solo che aumento la larghezza di x |
| -pack .3 -side left \ | nella parte prima espanza. |
| -expand true -fill x | |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left\| Se espando due comandi questi si mettono in modo |
| -expand true | equidistante l'un l'altro |
-------------------------------------------------------------------------------
| -pack .1 .2 -side left\| Uguale a prima solo che ora saturo i bordi |
| -expand true - fill \ | |
| both | |
-------------------------------------------------------------------------------
Ex claro? Provate e capirete meglio!
Ora dovreste capire il semplicissimo programma, neanche tanto curato Euro v1.0:
--------INIZIO-----------
#!/usr/bin/wish
wm title . "Euro v1.0"
wm resizable . 0 0
. configure -bg white
label .titolo -text "Convertitore" -bg white
label .titolo1 -text "EURO-LIRE" -bg red
pack .titolo .titolo1
set a 0
set b 0
label .titolo2 -text "Euro: " -bg white
entry .euro -textvariable a
label .lire -text "Lire: $b" -bg white
pack .titolo2
pack .euro -side top
pack .lire -pady 10
button .b1 -text Converti -command {euro-lire}
button .esci -text Esci -command {exit}
pack .b1 .esci -side left -pady 10
proc euro-lire {} {
global a
set b [expr $a*1936.27]
.lire configure -text "Lire: $b"
pack .lire
}
-------FINE--------------
Provate a fare l'inverso, da Lire a Euro...
Listbox
Le listbox mediamente si fanno in un frame poichË cosÏ compaiono come oggetto unico.
I comandi comunque sono 2:
listbox .nome opzioni
scrollbar .nome opzioni
Esempio:
frame .frame
scrollbar .frame.scroll -command ".frame.list yview"
listbox .frame.list -yscroll ".frame.scroll set" -width 20 -height 16 -setgrid 1
Che vuol dire:
Creo un frame di nome .frame. Faccio una barra di scorrimento di nome .frame.scroll
e che mi permette di muovere attravero la lista di .frame.list in verticale (yview).
Poi creo una lista di nome .frame.list verticale (-yscroll) legata alla barra di
prima (.frame.scroll set) di larghezza 20 e altezza 16. Setgrid imposta la larghezza
tra una linea e l'altra.
Eventi
Gli eventi sono creati grazie al comando bind. Gli eventi sono legati in prevalenza
al mouse e ai suoi click. Si puÚ quindi considerare il pulsante un evento.
Vediamo l'esempio:
--------INIZIO-------------
#!/usr/bin/wish
frame .f -width 100 -height 100
bind .f <Button-1> {puts "Button 1 premuto"}
bind .f <Button-2> {puts "Button 2 premuto"}
bind .f <ButtonRelease-1> {puts "Button 1 rilasciato"}
bind .f <Double-Button-1> {puts "Doppio click Button 1"}
bind .f <Any-Motion> {puts "Posizione $x, $y"}
pack .f
-------FINE------------
Nel seguente programma possiamo vedere come creato un frame di nome .frame collego
ad un click sul frame la scritta Button 1 premuto, ecc...
Quindi possiamo osservare che gli eventi possibili sono:
<Button-1> CioË Pressione del pulsante 1 del mouse
<Button-2> CioË Pressione del pulsante 2 del mouse
<Button-3> CioË Pressione del pulsante 3 del mouse
<ButtonRelease-1> Rilasciamento del pulsante 1
<ButtonRelease-2> Rilasciamento del pulsante 2
<ButtonRelease-3> Rilasciamento del pulsante 3
<Double-Button-1> Doppio Click
<Any-Motion> CioË indica nella variabili $x e $y la posizione del mouse.
Cose carine
- Il comando FOCUS .nome_di_qualcosa_gi‡_esistenza permette di selezionarlo e, al
passaggio del mouse di colorarlo.
ES:
button .ciao -text ciao
focus .ciao
pack .ciao
- I mille wm:
wm title . "nome finestra"; # GIA VISTO!
wm geometry . 200x200; #dimensioni della finestra
wm iconify . ; #iconifica la finestra
- destroy .x Distrugge la finestra
- Catturare il mouse:
grab .x
grab release .x
Ove x Ë il nome della finestra in questione.
- showVars Mostra le variabili in continuo aggiornamento
- Creare finestre di dialogo. Quelle che ti dicono: Attenzione...
mkdialog .nome "Attenzione..." $msg warning "Ok "Annulla" "Cancella"
Poi le opzioni si modificano in base al $msg.
Esistono ancora in questo argomenti i tk_messageBox che vanno usati cosÏ:
tk_messageBox -icon error\
-type ok \
-message "Attenzione...."
return 1
Ove icon indica quella di errore (Ë predefinita), type indica il pulsante e
message indica il messaggio da inserire.
- Menu
Per creare menu possono essere creati attraverso il comando menubutton.
menubutton .ciao -text "File" -menu .ciao.1 -bd 3 -relief raise
menu .ciao.1
ove -text indica il testo del menu, -menu indica il menu contenente tutte le
opzioni, -bd indica il bordo e -relief indica il tipo di bordo (cioË in rilievo).
Il secondo comando indica un menu a tendina.
Qui dentro posso inserire ciË che voglio, dalle etichette a dei pulsanti:
.ciao.1 add opzione funzioni
pack .ciao
Le opzioni in questione sono:
cascade Crea i menu che poi si aprono in sotto menu
radio Crea i menu con un pallino
checkbutton Crea i menu con un rettangolino
command Crea il classico pulsante nel menu
radiobutton Crea un rombo
separation Crea una separazione
Le funzioni possono essere:
-label "ciao" Che vuol dire il nome del pulsante sar‡ ciao
-command {} Indica che tra le parentesi ci sar‡ un comando o una procedura che
partir‡
ES:
---INIZIO---------
#!/usr/bin/wish
label .a -text CIAO!!
menubutton .ciao -text "File" -menu .ciao.a -bd 3 -relief raise
menu .ciao.a
.ciao.a add command -label "Esci1" -command {exit}
.ciao.a add separator
.ciao.a add radio -label "Esci2" -command {exit}
pack .ciao
-------FINE-----------
- Le scale di graduazione sono tipo le levette degli HI-FI. Si fanno cosÏ:
scale .ciao -orient horizontal -length 100 -from 0 -to 1 -tickinterval 0.5 \
-variable t -resolution 0.1
Che vuol dire: Creo una scala di nome .ciao in orizzontale (orient horizontal, ma
poteva esser anche verticale (orient vertical), che va (from) da 0 a 1 -Fai che il
cursore si trovi inizialmente (tickinterval) a 0.5, che la posizione definitiva
sia insita nella variabile t e che la scala di risoluzione (resolution) sia di
0.1.
Chiaro?
TCL/TK e Internet
Avete creato un bel programmino e volte visualizzarlo su internet. Potete farso
grazie ai programmi browser pi˘ famosi Netscape e Internet Explorer. Dovete
scaricarvi le sorgenti e gli eseguibiliti di un programma chiamato plugin
scaricabile all'indirizzo:
http://sunscript.sun.com/plugin/download.html
Qui potete scaricarvi questo programma. Ovviamente per ragioni di sicurezza (cazzo!)
hanno tolto i seguenti comandi:
cd, exec, fconfigure, file, glob, pwd, socket, bell, clopboard, grab, menu, send,
tk, toplevel, wm.
Non vi preoccupate se non li conoscete. Questi hanno funzioni particolari che,
magari, prima o poi vi spiegherÚ in un corso avanzato di questo programma.
Si possono ripristinare questi comandi andando a ritoccare il file plugin.tcl
contenuto nella directory:
- per Linux: ~/.netscape/tclplug/2.0/config
- per Windows: \config nella directory d'installazione.
**********************************************************************************
Ma, non vi preoccupate: Ë da un po' che sto cercando di programmare un eseguibile
attraverso Web capace di modificare quessto file per poi giocare con il computer
della vittima.... (ovviamente quello che qui ho detto non Ë affatto vero, io non
vorrei mai intaccare un computer non mio,ecc...)
**********************************************************************************
Comunque mediamente questo programma non Ë intallato automaticamente. Quindi...
Se avete voglia di scaricarvelo, le righe di HTML per far partire il file (di nome
prova.tcl) Ë questo:
<HTTML>
<HEAD>
<TITLE>Programma di prova!!</TITLE>
</HEAD>
<BODY>
<EMBED SRC="prova.tcl" WIDTH="300" HEIGHT="300">
</BODY>
</HTML>
Se non sapete cosa questo sia, leggetevi la mia guida sull'HTML sempre su questo
sito!
Ovviamente vi ricordo che la larghezza della pagina deve essere quella del
programma.
Questo file HTML deve essere salvato come nome_che_volete.html . Quindi
visualizzatelo.
Creare un database
Lo sapete cos'Ë mSQL? mSQL Ë un programma per Linux che permette di creare database.
Questo programma poi si Ë sviluppato in pi˘ direzioni fino ad una versione
compatibile con tcl. Questa permette di creare database al pari di ACCESS della
Microsoft. Mica male! E' solo questione di pratica. Pensavo di inserire qui un mio
programma di database per libri creato per schedare quelli di casa mia, ma dato che
il programma Ë molto lungo ed esula dal "base" di questo programma, penso che lo
spieghero in un "avanzato".
Comunque sappiate che tcl Ë molto flessibile e permette di cooperare con molti altri
linguaggi, arrivando a dei livelli incredibili.
-----------------FINE--------------------
Direi che con questo Ë tutto!
Per informazioni & C.
Michael Bakunin
bakunin@meganmail.com