in reply to Tk: Binding Keys to events

Hi tamaguchi,

Note that you don't have to pass the subroutine as an anonymous subroutine within a list reference.

That is to say, although it will work to do:

$mw->bind( '<Control-KeyPress-a>', [sub {print "Button a has been pr +essed\n"}] ); $mw->bind( '<Control-KeyRelease-a>', [sub {print "Button a has been re +leased\n"}] );

One often specifies either a simple anonymous subroutine:

$mw->bind( '<Control-KeyPress-a>', sub {print "Button a has been pre +ssed\n"} ); $mw->bind( '<Control-KeyRelease-a>', sub {print "Button a has been rel +eased\n"} );

or a simple anonymous list:

$mw->bind( '<Control-KeyPress-a>', [ \&say_button_pressed, "a" ]); $mw->bind( '<Control-KeyRelease-a>', [ \&say_button_released, "a" ]); # Unlikely to do it this way unless the following subroutines are # longer, or likely to be called from multiple places... # sub say_button_pressed { printf "Button %s has been pressed\n", $_[0]; } sub say_button_released { printf "Button %s has been released\n", $_[0]; }

I tend to use the former, an anonymous subroutine, when the code is brief and simple, whereas the latter is better when the subroutine is long and complex.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Tk: Binding Keys to events
by tamaguchi (Pilgrim) on Oct 03, 2006 at 10:43 UTC
    Thank you all. What is the rationale for having the syntax '<Control-KeyPress-a>' wouldn´t be more clear to write <KeyPress-Control-a>'?
      It might well be more clear, but it doesn't work:
      #!/usr/bin/perl -w + use Tk; + use strict; use warnings; + my $mw = new MainWindow(); $mw->bind( '<KeyPress-Control-a>', sub {print "Button a has been press +ed\n"} ); $mw->bind( '<KeyPress-Control-a>', sub {print "Button a has been relea +sed\n"} ); MainLoop; # Produces ... bad event type or keysym "Control" at /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Tk/Derived.pm l +ine 469. # My version of Perl This is perl, v5.8.0 built for i386-linux-thread-multi

      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
        This program creates a yellow rectangle on a canvas. The rectangle is possible to move up, down, left, and right by the respective arrow keys.
        #!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; my $c = $mw->Scrolled('Canvas', -width => 200, -height => 200, -background =>'blue', -scrollregion => [ 0, 0, 500, 500 ] ); $c->pack(-expand => 1, -fill => 'both'); my $rect=$c->createRectangle(100, 100, 150, 150, -fill => 'yellow'); + $mw->bind('<KeyPress-Left>', sub{$c->move($rect, -5, 0);}); $mw->bind('<KeyPress-Right>', sub{$c->move($rect, 5, 0);}); $mw->bind('<KeyPress-Up>', sub{$c->move($rect, 0, -5);}); $mw->bind('<KeyPress-Down>', sub{$c->move($rect, 0, 5);}); my @coords_list = $c->coords($rect); MainLoop;
        Now I would like to be able to move the rectangle on the diagonal by pressing for example both up and right. To write:
        $mw->bind('<Right-KeyPress-Up>', sub{$c->move($rect, 5, -5);});
        ..is however not possible do you have any other suggestions how to bind two arrowkeys to an event?
        Hi tamaguchi,

        No, there's no way to do it using multiple keypresses (that I'm aware of).  And even if you could, there would be a problem when you held the 2 keys down, and relied on key repeats; whichever key you pressed "last" will dictate the direction that the object moves in.

        You can try it yourself by holding down the left and up arrow, for example; the initial movement might appear to be a "wobbly" northwest movement, but after the repeat kicks in, the square will only move left or up.

        My recommendation would be to assign a completely different set of keys.  For example, you could use the 8 keys centered around the "k":

        my $pbindings = { 'Key-j' => sub { $c->move($rect, -5, 0) }, 'Key-l' => sub { $c->move($rect, 5, 0) }, 'Key-i' => sub { $c->move($rect, 0, -5) }, 'comma' => sub { $c->move($rect, 0, 5) }, 'Key-u' => sub { $c->move($rect, -5, -5) }, 'Key-o' => sub { $c->move($rect, 5, -5) }, 'Key-m' => sub { $c->move($rect, -5, 5) }, 'period' => sub { $c->move($rect, 5, 5) }, }; + map { $mw->bind("<$_>" => $pbindings->{$_}) } (keys %$pbindings);

        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/