Search code examples
tcltk-toolkititcl

Tcl/Tk - Unable to attach class method as button command


I was trying to attach a method to a command button but got the following error message. Its working fine if i attach a proc.

How to do this?

% itcl::class a { 
    method test {} {puts test}
    constructor {} {
        button .t.b -command test; 
        grid config .t.b -column 0 -row 0
    } 
}

% a A

invalid command name "resize"
invalid command name "resize"
    while executing
"resize"
    invoked from within
".t.b invoke"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [list $w invoke]"
    (procedure "tk::ButtonUp" line 24)
    invoked from within
"tk::ButtonUp .t.b"
    (command bound to event)

Solution

  • Button callbacks are processed in the global context because buttons don't know about itcl classes and the callbacks happen at a time when the class isn't on the execution stack. This means that the callback needs to use one of the forms that allows external code to invoke the method:

    # The form with "$this test" is not preferred as it can go wrong with complex data.
    # It tends to show up when you tidy things up for a demo! Using [list] avoids trouble.
    button .t.b -command [list $this test]
    
    # The [namespace code] command picks up the current namespace context. That's what itcl
    # needs to work correctly.
    button .t.b -command [namespace code { test }]