Prev: Another suggestion/asking: background for canvas
Next: Simple Hack To Get $2000 To Your PayPal Account
From: Bruce on 14 Jul 2010 22:04 Bob wrote: > Ok, you certainly have more patience than I do. ;) ;) > > Here is the last iteration of many that I have tried. As I said, I am > pretty much chasing my tail at this point, so this may not be the code that > came closest to working. It is also stripped down to the point to just deal > with these variable issues I have been having. (BTW, is there any way to > just make a variable visible >from anywhere< >to anywhere< in the code? > The program I have in mind is not going to be so complex as to have to > protect variables. no - variable in a aproc default to local scope - use global to access global variables within a proc (code outside any proc is running in global scope already) if you don;t want to use tyhe global command you can allways be explicit and preace your vars with :: (like $::dit) also you can use a array for all you valss o you only need to declare one variable e.g. global GVars set GVars(dit) 1 set GVars(dah) 5 set GVars(space) 3 > > ############################################################################# > proc wpmcalc {wpm} { > set wpmper [expr {($wpm*.01)}] > } this function only sets the local variable wpmper inside the proc which immediatley leaves scope so is pointless > > proc init {} { > global dit dah space wpm ditlen wpmper > > } global command doesn't create any variables, only defines those varnames in the global scope for the current proc - so you probably want set dit 1 set dah 5 set space 3 set ditlen 1 set wpm 100 set wpmper 1.0 inside that proc to actually define the values > > init > > scale .dit -orient horizontal -label dit -variable dit > scale .dah -orient horizontal -label dah -variable dah > scale .space -orient horizontal -label space -variable space > scale .wpm -orient horizontal -label wpm -from 80 -to 100 -variable > wpm -command wpmcalc > > pack .dit > pack .dah > pack .space > pack .wpm > > set ditlen [expr {int($dit*$wpmper)}] > > ############################################################################## > > When all is said and done, I want 4 scale bars: > > One that will control the length of a dit. (call it dit) > One that will control the length of a dah (call it dah) > One that will control the length of a space between the other two elements. > (call it space) > One that will provide a value (0.8 to 1) that will be multiplied with each > of the other values, so as to increase or decrease all of them by the same > relative amount. (call it wpm or more accurately "speed") > (A related issue....this is where the 'wpm*0.01' code comes in....I also > struggled with how to make a scale bar go from 0.8 to 1.0, so I gave up and > went from 80 to 100). make sure you set the -resolution option or it default to 1 and rounds all values so you get a scale of 1 to 1 (the -digits option can be used to display them do you ever need the raw values of dit/dah/space? or only the modified values? if you only need the final values then the follwoing should get you going: Bruce proc build_gui {} { scale .dit -orient horizontal -label dit -command updateVars .dit set 1 scale .dah -orient horizontal -label dah -command updateVars .dah set 3 scale .space -orient horizontal -label space -command updateVars .space set 2 scale .wpm -orient horizontal -label wpm -from 0.80 -to 1.0 \ -resolution 0.01 -command updateVars .wpm set 1.0 pack .dit pack .dah pack .space pack .wpm button .b -text "Try Me" -command sample pack .b # init values from scales updateVars } proc updateVars {args} { global Vars set Vars(dit) [expr [.dit get] * [.wpm get]] set Vars(dah) [expr [.dah get] * [.wpm get]] set Vars(space) [expr [.space get] * [.wpm get]] puts "New Values are: --------------" parray Vars puts "-------------------------------" } proc sample {} { global Vars puts "" puts "Currently dit is $Vars(dit)" puts "$::Vars(dah) is the value of dah" puts "" } build_gui
From: Aric Bills on 14 Jul 2010 23:03 Bruce gave you some specific pointers with your code, so I won't go there, but let me explain a bit more about Tcl's variable scope model, which differs in some crucial respects from scope in most other languages. To answer your question about making a variable visible to anywhere from anywhere, the short answer is yes, but not in the same way you'd do it in C or a similar language. In C, you declare a variable global. In Tcl, you use qualified namespace variables, or you use convenience commands like [global] or [variable] that allow you to use unqualified names for namespace variables. In Tcl there are two types of variables: namespace variables and procedure variables. Namespace variables persist until they are explicitly destroyed, or until the Tcl interpreter in which they are defined is destroyed. Procedure variables persist only during the lifetime of the procedure in which they were declared. Within a procedure, variable names are treated as local (procedure) variables unless they contain namespace qualifiers (look up the namespace man page for more info), or unless, within that procedure, those variable names were declared to resolve differently. Two commands that change how variable names resolve within a procedure are [global] and [variable]. [global] declares that the following variable names refer to variables in the global namespace. [variable] declares that the listed variables should be linked to variables in the namespace that the procedure belongs to (all procedures belong to a namespace; so far, you've probably only created procedures in the global namespace). (The story with [variable] is actually more complicated, but we won't go into that.) Both [global] and [variable] have no effect on variable names in any other proc. Consider the following useless code (all procedures in this code are defined within the global namespace): set foo 1 set bar 2 proc useGlobalVars {} { global foo bar set foo 3 set bar 4 } proc useNamespaceVars {} { variable foo 5 bar 6 } proc useQualifiedVars {} { # "::" represents the global namespace set ::foo 7 set ::bar 8 } proc useLocalVars {} { set foo 9 set bar 10 } useGlobalVars; puts "useGlobalVars: $foo $bar" useNamespaceVars; puts "useNamespaceVars: $foo $bar" useQualifiedVars; puts "useQualifiedVars: $foo $bar" useLocalVars; puts "useLocalVars: $foo $bar" # (end of code) # The output will look like this: useGlobalVars: 3 4 useNamespaceVars: 5 6 useQualifiedVars: 7 8 useLocalVars: 7 8 In other words, in every procedure where you want access to a namespace variable, you have to either use [global], [variable], or qualified variable names; otherwise Tcl will treat variable names as local, even if you've declared those same names global in another procedure. I hope that helps. If not, please do ask for clarification. Aric
First
|
Prev
|
Pages: 1 2 3 Prev: Another suggestion/asking: background for canvas Next: Simple Hack To Get $2000 To Your PayPal Account |