[GRASS-dev] Tcl/Tk script integration in Grass

thierrygonon thierrygonon at mac.com
Sun Oct 15 10:24:30 EDT 2006


Hello everybody,

I'm very knew in programming and I'm just trying to add some easy to use 
tools for the vector datas in GRASS. My aim ( a command from my 
employer) is to make the building of a query (to use after with 
v.extract) very easy for people who don't know SQL syntax. For this, 
I've first made a simple bash script (that can probably be enhanced) 
that works fine. The next point is to provide it trough a GUI, inside 
GRASS... I've made a Tcl/Tk script that I've integrated in my GRASS 
installation (in 
/Applications/grass61cvs.app/Contents/Resources/grass-6.1.cvs/scripts), 
and add the line "exec $GRASS_WISH "$0" "$@", but it failed : the answer 
is "GRASS_WISH : no such variable". If I don't use the "$0" "$@", a new 
wish start, but wait for me to start manually (via file/source) a script...

Can anyone help me ??

Here's my code, it will be easier to talk with it !!

Thierry Gonon
2 place de l'Eglise
01150 LAGNIEU
France
-------------- next part --------------
#!/bin/sh
#Version 0.5 (15 octobre 2006)
exec $GRASS_WISH "$0" "$@"

#Ouverture du script, ouverture ou creation du fichier
set GISDBASE [exec g.gisenv get=GISDBASE]
set LOCATION_NAME [exec g.gisenv get=LOCATION_NAME]
set DB_DRIVER [exec g.gisenv get=DB_DRIVER]
set DB_DATABASE [exec g.gisenv get=DB_DATABASE]
set DB_GROUP [exec g.gisenv get=DB_GROUP]

wm geometry . 800x600
wm title . "fichier de destination"
frame .file -borderwidth 4 -relief sunken
frame .file.s
label .file.int -text "Choix du fichier contenant la requête"
entry .file.file -textvariable filename

button .file.valid -text Valider -command {set idfile [open $GISDBASE/$LOCATION_NAME/$filename.sql w+]}
button .file.s.start -text "Construire la requête" -command {winq .query}

pack .file -side top
pack .file.int .file.file -side left
pack .file.valid -side bottom -expand true
pack .file.s -side left
pack .file.s.start -side bottom

#Création de la fenêtre de saisie de la requête

proc winq {parent} {
	global idfile filename w
	catch {destroy $parent}
	set w [toplevel $parent]
	
	frame $w.cadre -borderwidth 4 -relief sunken
	label $w.cadre.fi -text $filename
	frame $w.tablechoice -borderwidth 4 -relief sunken
	button $w.cadre.exit -text Abandonner -command exit
	
	pack $w.cadre
	pack $w.cadre.fi -side left
	pack $w.tablechoice -side left
	tablechoice
	pack $w.cadre.exit -side bottom
}

#Procédures de création des listes
#Liste des tables disponibles

proc tablelist {} {
	global DB_DRIVER DB_DATABASE DB_GROUP
	exec {db.tables driver=$DB_DRIVER database=$DB_DATABASE > /tmp/tables}
	exec {sed "/^public/!d" /tmp/tables | cut -d'.' -f2 > /tmp/table}
}

#Liste des colonnes disponibles

proc collist {} {
	global DB_DRIVER DB_DATABASE DB_GROUP ::tableselect
	exec db.columns driver=$DB_DRIVER database=$DB_DATABASE table=$::tableselect > /tmp/columns
}

#Liste des valeurs disponibles

proc vallist {} {
	global DB_DRIVER DB_DATABASE DB_GROUP ::tableselect ::colselect
	exec db.select table=$tableselect driver=pg sql="select $::colselect from $::tableselect" | sed "1d" | sort -u > /tmp/values
}


#Procédures de sélection
#Sélection de la table à interroger

proc tablechoice {} {
	global w
	tablelist
	set ::tables [split [read [open /tmp/table r]] "\n"]
	label $w.tablechoice.int -text "Tables disponibles :"
	listbox $w.tablechoice.list -selectmode single -setgrid true -listvariable ::tables
	button $w.tablechoice.valid -text Valider -command tablevalid
	
	pack $w.tablechoice.int -side top
	pack $w.tablechoice.list -side top -fill x -padx 5
	pack $w.tablechoice.valid -side top
}

#Sélection de la colonne interrogée

proc colchoice {} {
	global w
	collist
	set ::col [split [read [open /tmp/columns r]] "\n"]
	label $w.colchoice.int -text "Colonnes disponibles :"
	listbox $w.colchoice.list -selectmode single -setgrid true -listvariable ::col
	button $w.colchoice.valid -text Valider -command colvalid
	
	pack $w.colchoice
	pack $w.colchoice.int -side top
	pack $w.colchoice.list -side top -fill x -padx 5
	pack $w.colchoice.valid -side top
}

#Sélection du terme de comparaison

proc relchoice {} {
	global w
	set ::rel [list < <= = => > différent contient "ne contient pas"]
	label $w.relchoice.int -text "Colonnes disponibles :"
	listbox $w.relchoice.list -selectmode single -setgrid true -listvariable ::rel
	button $w.relchoice.valid -text Valider -command relvalid
	
	pack $w.relchoice
	pack $w.relchoice.int -side top
	pack $w.relchoice.list -side top -fill x -padx 5
	pack $w.relchoice.valid -side top
}

#Sélection de la valeur de référence

proc valchoice {} {
	global w
	vallist
	set ::val [split [read [open /tmp/values r]] "\n"]
	pack $w.valchoice
	if {$::val=>20} {
	label $w.valchoice.int -text "Valeurs disponibles :"
	listbox $w.valchoice.list -selectmode single -setgrid true -listvariable ::val
	
	pack $w.valchoice.int -side top
	pack $w.valchoice.list -side top -fill x -padx 5
	set ::valselect [$w.valchoice.list curselection]
	}
	{label $w.valchoice.int -text "Trop de valeurs. Entrée individuelle."
	entry $w.valchoice.val -textvariable ::valselect
	
	pack $w.valchoice.int -side top
	pack $w.valchoice.val -side top -fill x -padx 5
	}
	button $w.valchoice.valid -text Valider -command valvalid
	pack $w.valchoice.valid -side top
}

#Autre clé de tri ?

proc other {} {
	global w
	label $w.other.int -text "Voulez-vous ajouter une autre clé de tri ?"
	radiobutton  $w.other.yes -text "oui" -variable ::otherkey -value 1
	radiobutton  $w.other.no -text "non" -variable ::otherkey -value 0
	button $w.other.valid -text Valider -command othervalid
	
	pack $w.other
	pack $w.other.int -side top
	pack $w.other.yes -side top -fill x -padx 5
	pack $w.other.no -side top -fill x -padx 5
	pack $w.other.valid -side top
}

#Lien entre les clés de tri
proc linq {} {
	global w idfile
	frame $w.linq -borderwidth 4 -relief sunken
	label $w.linq.question 	"Quel sera le lien avec la clé de tri précédente ?"
	radiobutton $w.linq.and -text ET -variable linquery -value AND
	radiobutton $w.linq.or -text OU -variable linquery -value OR
	
	pack $w.linq -side top
	pack $w.linq.question -side top
	pack $w.linq.and $w.linq.or -side right
	
	puts $idfile " "
	puts $idfile $linquery
	puts $idfile " "
	flush $idfile
}

#Procédures de validation des différents choix
#Validation de la saisie de la table

proc tablevalid {} {
	global w idfile ::tables
	set tableselect [$w.tablechoice.list curselection]
	if {$tableselect!=""} {
		set idfile2 [open $GISBASE/$LOCATION_NAME/$filename.table w+]
		puts $idfile2 $tableselect
		close $idfile2
		colchoice
	} else {error}
}

#Validation de la saisie de la colonne

proc colvalid {} {
	global w idfile ::col
	sel colselect [$w.colchoice.list curselection]
	if {$colselect!=""} {
		puts $idfile $colselect
		puts $idfile " "
		flush $idfile
		relchoice
	} else {error}
}

#Validation de la saisie du terme de comparaison

proc relvalid {} {
	global w idfile ::rel
	sel relselect [$w.relchoice.list curselection]
	if {$relselect!=""} {
		puts $idfile $relselect
		puts $idfile " "
		flush $idfile
		valchoice
	} else {error}
}

#Validation de la saisie de la valeur

proc valvalid {} {
	global w idfile ::valselect
	if {$valselect!=""} {
		puts $idfile "\""
		puts $idfile $::valselect
		puts $idfile "\""
		flush $idfile
		other
	} else {error}
}

#Validation de la saisie de la valeur

proc othervalid {} {
	global w idfile ::otherkey
	if {$::otherkey=1} {
		linq
	} else {close}
}

#Erreur en cas de non-sélection
proc error {} {
	global w
	set y [toplevel $parent]
	
	frame $y.cadre -borderwidth 4 -relief sunken
	label $y.cadre.icone -bitmap warning
	message $y.cadre.msg -justify left -width 250 -pady 30 -text "Veuillez sélectionner une valeur avant de valider !"
	button $y.boutOK -text OK -command {catch {destroy $y}}
	
	pack $y.cadre -side top
	pack $y.cadre.icone -side left
	pack $y.cadre.msg -side right
	pack $y.boutOK -side bottom
}

#Fermeture de tous les fichiers, suppression des variables...
proc close {} {
	global w idfile filename
	close $idfile
	destroy $w
	unset w idfile idfile2 filename ::tableselect ::colselect ::valselect ::tables ::col ::rel ::val ::otherkey
	exec {rm /tmp/tables}
	exec {rm /tmp/table}
	exec {rm /tmp/columns}
	exec {rm /tmp/values}
}


More information about the grass-dev mailing list