GUIs with TCL, Tk and TclOO
notes about some more obscure things when building GUIs with TCL/Tk using TclOO. i'll describe windows here, but most also is the case for other, less special widgets.
referencing methods and variables
as Tk is in another namespace than our objects, variables and methods need to be properly
referenced. this uses self
and varname
.
instance variables
variable bar
pack [ ttk::label .foo -textvariable [ my varname bar ] ]
instance methods
method foo {} {
puts "method foo called"
}
pack [ ttk::button .foo -text "foo" -command [ list [self] foo ] ]
a list
is constructed to defer evaluation of the objects foo
method until the command is called.
path in constructor
to create more than one instance of a class representing a widget the Tk-path has to be stored internally.
package require TclOO
oo::class create MyWindow {
constructor { _path } {
variable path $_path
my ui
}
method ui {} {
variable path
toplevel $path
wm title $path "window title"
pack [ ttk::button $path.close -text "Close" -command [ list [ self ] destroy ] ]
}
destructor {
variable path
destroy $path
}
}
this can be instanciated with
MyWindow new .foo
hiding the default toplevel window
useful to remove the default window as it complicates things to reuse the path .
for an
instance of a class based window.
wm withdraw .
waiting for another window
if one wants to wait for another modal dialog window, a solution is to use
vwait
to wait for a variable being updated.
oo::class create Foo {
constructor { _path } {
variable path $_path
toplevel $path
wm title $path "modal"
pack [ ttk::button $path.openmodal -text "open modal" -command [ list [ self ] waitForModal ] ]
}
method setx {newx} {
variable x
set x $newx
}
method waitForModal {} {
variable x
set x [ Bar new .modal [ list [ self ] setx ] ]
vwait [ my varname x ]
}
}
oo::class create Bar {
constructor {_path _callback } {
variable path $_path
variable callback $_callback
toplevel $path
wm title $path "modal"
pack [ ttk::button $path.close -text "callback" -command [ list [ self ] call ] ]
}
method call {} {
variable path
variable callback
{*}$callback "value from modal"
destroy $path
}
}