use Tk;
$top = tkinit; # default application name and display # # create lots of widgets # tkmainloop; # # Not reached here. # Subroutines can go below or at the top (or wherever you like). # sub acallback { # ... } sub anothercallback { # ... }tkinit takes up to three arguments (all optional). The first is the application name which defaults to the basename of $0. The second is the display to use (defaults to DISPLAY from the environment...perl's magic environment in fact). The third is a sync flag which, if true, makes all communication with the X server synchronous (slow, but occasionally useful for debugging).
Example:
Tk/Tcl button .b -text foo tkperl $b = Button::new($top, "-text" => "foo");$b above is a reference to the pathname, blessed into the appropriate widget package. A previous command of something like
$top = tkinit;is assumed above and in other examples. In Tk/Tcl creation of a widget causes creation of a new Tcl command whose name is the widget's pathname and invoking this command with first argument foo invokes method foo on that widget. In tkperl, the widget's methods are real methods in the appropriate package and so one can use the blessed reference to invoke them.
Example:
Tk/Tcl .b flash .b configure -textvariable bar tkperl $b->flash(); $b->configure("-textvariable" => $bar);There are a few minor differences in names: delete , index and select are perl keywords and have been renamed tkdelete, tkindex and tkselect. Tcl `submethods' such as .foo scan mark have been turned into single methods: scanmark, scandragto, selectclear, selectadjust, selectfrom, selectto. If the configure method of a widget is given one (extra) argument, it is taken to be an option name and a five element list consisting of (option name, database name, database class, default value, current value) is returned, unless the option name is a synonym in which case the two element list (option name, real option name) is returned. If no (extra) arguments are given to the configure method (e.g. C<@conf = $w->configure();>) then a list is returned consisting of a list ref for each option understood by the widget. Dereferencing each of those list refs gives a five or two element list as mentioned above.
$w->configure("-slave" => $slave, "-method" => $method);Callback behaviour depends on whether $slave is a blessed reference or just an ordinary value. If $slave is a blessed reference then the corresponding method is invoked in the package of the blessed reference and the first argument is $slave itself. In other words, if $method is "foo" then it's the same as doing
$slave->foo();in pure perl. If method is blank (some widgets have non-blank default method; most have blank default method) then no callback happens. On the other hand, if $slave is not a reference (in particular, if $slave is not defined), then $method is taken to be an ordinary subroutine and it is called with $slave as its first argument (or undef if $slave not defined). $method can be either the name of a subroutine ("foo" or "Somepackage::foo"), a subroutine reference such as \&foo or an anonymous subroutine reference such as
sub { do_something; do_something_else }In this last case, you not only get the ability to write callback code directly without having to name it but the code is also compiled before execution starts--the best of both worlds. In all cases, the callback routines are passed extra arguments in precisely the same situations as in Tk/Tcl (e.g. scrollbar callbacks).
Example
Tk/Tcl .r configure -variable foo -value green tkperl $r->configure("-variable" => $foo, "-value" => "green");Any alteration to that variable is tracked by the widget and it updates itself as necessary.
tkbind($w, "<SomeEventName>", "somemethod");$w can be a blessed reference to a widget or a widget pathname or a string corresponding to the class (e.g. "Button") or "all". The third argument is a method, as described in a previous section. An optional fourth argument is the slave/clientdata.
$w = Listbox::new($foo);then you can pack it with
tkpack $w;
Tk/Tcl update (processes all events and when-idle tasks) tkperl update;
Tk/Tcl update idletasks (processes only when-idle tasks) tkperl idletasks;
When $method is called, it is called with the following arguments: $method($slave, $toread, $towrite, $exception); If $selectfor contained "r", then $toread is
undef if FILEHANDLE is not readable 0 if FILEHANDLE is readable and at EOF n > 0 if FILEHANDLE is readable and `n' bytes can be read without blocking from FILEHANDLE.In the third case, you can use sysread(FILEHANDLE, $foo, $toread) to get those bytes into $foo. $toread is obtained by using the FIONREAD ioctl on FILEHANDLE. The program will die with an error if $method is called and this ioctl is not available.
If $selectfor contained "w", then $towrite is set to the result of the TIOCOUTQ ioctl. This value does not seem to be quite as obviously useful as that of FIONREAD in the read case, though.
If $selectfor contained "e", then $exception is true if and only if the select(2) indicated an exception on FILEHANDLE. The meaning of this is dependent on the flavour of Unix.
The "rwe" mask is set per file descriptor. Calling addasyncio again on the same file descriptor will replace the mask, $method and $slave with the new ones given. The command delasyncio(FILEHANDLE) removes the file handler created for FILEHANDLE. This may be necessary before closing the FILEHANDLE (a) to free up some internal memory and (b) to prevent the handler from getting called erroneously if a newly opened file reuses the underlying file descriptor. I can't piggy-back anything on perl's close() command, unfortunately, without changing perl itself.
Tk/Tcl wm maxsize . 4000 4000 tkperl wm("maxsize", $top, 4000, 4000);
tclcmd("foo", "argument", "andanother", "etc");Notice that none of this touches the Tcl parser. Make sure you pass each argument separately. Where the command expects a widget argument, you can always give it a widget object rather than a pathname and it will be automatically converted to the pathname that the underlying Tk command expects. The tclcmd command returns a string result like any Tcl command does so if it returns a Tcl list, you're on your own for parsing it.
package Scrolledlistbox; @ISA = (Listbox, Scrollbar); sub new { # create a new listbox $l # create a new scrollbar $s # link the two together bless {Listbox => $l, Scrollbar => $s}; }and then later have
$sl = Scrolledlistbox::new($parent);in package main, then $sl will understand the methods of both Listbox and Scrollbar and the methods will be applied to the appropriate widget ($l or $s). Certain tkperl commands look for special keys too (e.g. focus looks for Focus). You can also use the hash to cache any other necessary data for your new widget. For examples, see F
use Tk;after your package declaration will ensure that all necessary subroutines are defined and imported into your package's namespace. If you need to postpone any initialisation until after tkinit has happened (class bindings for all widgets need to be delayed in this way) then you can push your package name onto @Tk::CLASSINIT. When tkinit happens and the toplevel widget is created the method classinit is invoked in each package in the list @Tk::CLASSINIT.
BEGIN { require Tkperldb; }(making sure that perl knows where to find its library, either because perl5 is properly installed or by setting PERL5LIB yourself). Then use
perl -d scripttodebug