From: cattaghia on
Hi everyone!

I pass months studying Tcl and I still get stuck on those small
things. For example, I read that using inline scripts for the "-
command" option in buttons is not recommended and may be deprecated in
future versions of Tk.

So, with this rule in mind, I tried to play with an unknown handler
which might allow the user to hand-input a value as if it was returned
from the called-but-inexistant procedure. Now it looks like I got a
complete-flop design, but I still can't understand why:


# ###########################
# UNKNOWN HANDLER
# ###########################

rename unknown orig_unknown

proc DlgUnknown_Return { wnd } {
set val [$wnd.frmRet.entRet get]
destroy $wnd
return -level 2 $val
}

proc DlgUnknown_Go { wnd arglist } {
destroy $wnd
orig_unknown $arglist
}

proc unknown { args } {
toplevel .dlgUnknown -height 200 -width 400
wm title .dlgUnknown "Procedure not found!"

set msg [::msgcat::mc "A non-defined procedure or command was\
called:\n\n\t"]
append msg [lindex $args 0] [::msgcat::mc "\n\nwith these values as\
arguments:\n\n"]
foreach a [lrange $args 1 end] {
append msg "\t" $a "\n"
}

ttk::label .dlgUnknown.lbl1 -anchor center -text $msg
pack .dlgUnknown.lbl1 -anchor n -expand 1 -fill x -pady 5

ttk::frame .dlgUnknown.frmRet
pack .dlgUnknown.frmRet -anchor n -fill x -pady 2

ttk::label .dlgUnknown.frmRet.lbl2 -justify right -anchor e \
-text [::msgcat::mc "Enter a possible return value: "]
ttk::entry .dlgUnknown.frmRet.entRet

pack .dlgUnknown.frmRet.lbl2 -side left -anchor w -fill x
pack .dlgUnknown.frmRet.entRet -side left -anchor w -fill x

ttk::button .dlgUnknown.btnRet -text [::msgcat::mc "Return this
value"]\
-command "DlgUnknown_Return .dlgUnknown"
pack .dlgUnknown.btnRet -anchor n -fill x

ttk::button .dlgUnknown.btnGo\
-command "DlgUnknown_Go .dlgUnknown [list $args]"\
-text [::msgcat::mc "Just go ahead (possible crash)..."]
pack .dlgUnknown.btnGo -anchor n -fill x

raise .dlgUnknown
lower .
tkwait window .dlgUnknown

}


# TEST
set b [doitbabe one two three]
puts "Returned value: $b"
unset b

# #####################################

I tried lots of different combinations for the "-command" option in
the buttons, tried to interpret the Dodekalogue, and in every attempt
I got everything but what I expected. Not mentioning, surely, the fact
that by any means I could not have the hand-written value returned to
the procedure/script which called the inexistant procedure. In some
attempts, I got a mysterious "window name dlgUnknown already exists in
parent" for which I could not find any references both here in clt and
in the wiki. Actually, this code pasted here is my last attempt, and I
found it really, really surprising... So, please, what am I doing
wrong *again*?


Thank you!

Fabricio Rocha
Brasilia, Brasil
(waiting for the delivery of the new Ousterhout's book copy I bought
from Amazon. I hope this will allow me to avoid other ashaming
questions like that)
From: rf on
I get the dialog window, when I omit all ttk:: prefixes.
Yet proc unknown does not return a value.
Suggestion: add option -textvariable THIS to the entry command and
insert
"global THIS; return $THIS" before unknown's closing brace.

best regards
Roland Frank
From: rf on
forget to mention, that I 'caught' the toplevel command.
if {[catch {toplevel ....} err]} {
puts $err
}
which is triggered with following message:
unknown:bgerror {bad option "-level": must be -code, -errorcode, or -
errorinfo}

Roland Frank

From: Don Porter on
rf wrote:
> which is triggered with following message:
> unknown:bgerror {bad option "-level": must be -code, -errorcode, or -
> errorinfo}

When you have a script that needs Tcl release 8.5 or later, do not
attempt to evaluate it in releases 8.4 or earlier.

You might want to send feedback to the authors that a
[package require Tcl 8.5] in their script would be an improvement.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald.porter(a)nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
From: cattaghia on
Well, after finding one of the many ingenious snippets from Richard
Suchenwirth in the Wiki, I think I got what I wanted with that:

# ###########################
# UNKNOWN HANDLER
# ###########################

rename unknown orig_unknown

proc unknown { args } {

# Create the message to be shown
set msg [::msgcat::mc "A non-defined procedure or command was\
called:\n\n\t"]
append msg [lindex $args 0] [::msgcat::mc "\n\nwith these values as\
arguments:\n\n"]
foreach a [lrange $args 1 end] {
append msg "\t" $a "\n"
}

toplevel .dlgUnknown -height 200 -width 400
wm title .dlgUnknown [::msgcat::mc "Procedure not found!"]
wm protocol .dlgUnknown WM_DELETE_WINDOW

ttk::label .dlgUnknown.lbl1 -anchor center -text $msg
pack .dlgUnknown.lbl1 -anchor n -expand 1 -fill x -pady 5

ttk::frame .dlgUnknown.frmRet
pack .dlgUnknown.frmRet -anchor n -fill x -pady 2

ttk::label .dlgUnknown.frmRet.lbl2 -justify right -anchor e \
-text [::msgcat::mc "Enter a possible return value: "]
ttk::entry .dlgUnknown.frmRet.entRet

pack .dlgUnknown.frmRet.lbl2 -side left -anchor w -fill x
pack .dlgUnknown.frmRet.entRet -side left -anchor w -fill x

ttk::button .dlgUnknown.btnRet -text [::msgcat::mc "Return this
value"]\
-command {set unkwhaddado [list VAL [.dlgUnknown.frmRet.entRet
get]]}
pack .dlgUnknown.btnRet -anchor n -fill x

ttk::button .dlgUnknown.btnGo\
-command {set unkwhaddado [list NOVAL {}]} \
-text [::msgcat::mc "Just go ahead (possible crash)..."]
pack .dlgUnknown.btnGo -anchor n -fill x

raise .dlgUnknown
vwait unkwhaddado
# TEST LINE
puts "Got past the vwait command... unkwhaddado is $::unkwhaddado"
destroy .dlgUnknown

if { [lindex $::unkwhaddado 0] eq "VAL" } {
# This may have to be changed for returning to the right caller
set retval [lindex $::unkwhaddado 1]
unset ::unkwhaddado
return $retval
} else {
# Go ahead with the original unknown procedure
unset ::unkwhaddado
orig_unknown $args
}
return
}


# TEST
set b [doitbabe one two three]
puts "Returned value: $b"
unset b

# #############################
# #############################

The buttons -command option was changed to set a variable in the root
namespace, instead of calling a procedure for reading the entry's
value. Yeah, works, but let's hope that another program or procedure
also uses a global variable with the unlikely name of "unkwhaddado".

Isn't there a more elegant solution? Or is this really The Right Way
for simple custom dialogs like this? If so, how to apply in such cases
the rule of "thou shall use the -command option only for calling a
proc"?

Anyway, thanks for the suggestions. I still had not understand why the
code would work if the toplevel's creation was "catched"...

Cheers!

Fabricio Rocha