From: spencer@med.umich.edu (Spencer W. Thomas)
Subject: Re: Tk/Wish beginner seeks advice
Date: Tue, 12 Jan 93 10:19:13 EST
Organization: University of Michigan



The -command is executed at "top level", so will only recognize global
variables.  However, in your example, the variable ${w.bot.raval}
should be expanded when the button command is executed (since it's in
""s).  Actually, your problem is that there is no variable
${w.bot.raval}.  You really want to say $w.bot.raval (in the first
case, it's looking for a variable named w.bot.raval.  In the second,
it expands $w, then appends the string .bot.raval.)

> button $w.bot.dismiss -text "go away" -command \
>	"puts stdout $var1; puts stdout $var2; destroy $w"

I'm confused about this one.  Are you sure this is how it appears in
your program?  You didn't put it in {}s?  Because, the way you've
written it, $w should get evaluated when the button is created, and so
should $var1 and $var2.  Maybe a concrete example will help:

global var1 var2
set var1 1
set var2 2

proc makebutton {} {
	# Name of window inside which we will create the button
	set w .top
	button $w.dismiss -text "go away" -command \
		"puts stdout $var1; puts stdout $var2; destroy $w"
	pack append $w $w.dismiss {top}
}

# This will cause an error: "Error: can't read "var1": no such variable"
# Because var1 and var2 are not declared global inside the proc makebutton
makebutton

# Retype proc makebutton with a global var1 var2 declaration, and try again
makebutton

# Change values of var1 and var2
set var1 5
set var2 6

# Now, if you press the go away button, it will print 1\n2 then
# destroy the window.  This is because the variables $var1 and $var2
# were evaluated when the button was created.  Try
.top.dismiss configure -command
# The result is
# -command command Command {} {puts stdout 1; puts stdout 2; destroy .top}
# Next try:

proc makebutton {} {
	# Don't need global because we won't evaluate var1, var2 yet
	# Name of window inside which we will create the button
	set w .top
	# Use {} to delay variable evaluation until later.
	button $w.dismiss -text "go away" -command \
		{puts stdout $var1; puts stdout $var2; destroy $w}
	pack append $w $w.dismiss {top}
}

# Now 
.top.dismiss configure -command
# gives
# -command command Command {} {puts stdout $var1; puts stdout $var2; destroy $w}
# But if you push the button, you get
#  5
# 6
# can't read "w": no such variable
# Because $w was local to the proc makebutton, and doesn't exist any
# more when you push the button.
# But, if you change var1 or var2, the printed result follows the change.
#
# Finally, to get it right:
#

proc makebutton {} {
	# Name of window inside which we will create the button
	set w .top
	# Quote $var1 and $var2 with \ to delay evaluation.
	button $w.dismiss -text "go away" -command \
		"puts stdout \$var1; puts stdout \$var2; destroy $w"
	pack append $w $w.dismiss {top}
}

# Now it's right:
.top.dismiss configure -command
# -command command Command {} {puts stdout $var1; puts stdout $var2; destroy .top}

=S
--
=Spencer W. Thomas 		|  Info Tech and Networking, B1911 CFOB, 0704
   "Genome Informatician"	|  Univ of Michigan, Ann Arbor, MI 48109
Spencer.W.Thomas@med.umich.edu	|  313-747-2778, FAX 313-764-4133
Newsgroups: comp.lang.tcl