Search code examples
perlwxwidgetswxperl

Can't get EVT_KEY_DOWN to fire in wxPerl


In this case $self is a subclass of Wx::Frame and I can add controls, menus, etc to the frame. However I cannot add key events. I am using the following to add the key event:

  EVT_KEY_DOWN($self,  \&_process_char);

The _process_char function looks like this:

sub _process_char {
   my ($evt) = @_;
   warn 'key pressed';
}

The event doesn't fire. What am I doing wrong? How do I get key down events to work with wxperl?


Solution

  • It has to do with event propagation -- a textctrl handles keydown/keyup events, and the default one (default textctrl handler) won't propagate these events UP to a frame. If you want your handler to be called bind to wxTheApp() or the textctrl. Here is an example where not all keys are propagated

    #!/usr/bin/perl --
    use strict; use warnings;
    use Wx ();
    
    Main( @ARGV );
    exit( 0 );
    
    sub Main {
        local $|  = 1;
        my $app   = Wx::SimpleApp->new;
        my $frame = Wx::Frame->new( undef, -1, "type stuff ", ([250,150])x2 );
        my $text  = Wx::TextCtrl->new( $frame, -1,"", );
    
        $app->SetTopWindow( $frame );
    
        my $target = @_ ? $frame : $text;
        Wx::Event::EVT_KEY_DOWN( $target ,  \&Frobnicate );
        Wx::Event::EVT_KILL_FOCUS($app,  sub{  Wx::wxTheApp()->ExitMainLoop });
    
        $app->{counter} = 0;
        $frame->Show;
        $text->SetFocus;
        $app->MainLoop;
    }
    
    sub Frobnicate {
        my( $widget, $kev )=@_;
        my $app   = Wx::wxTheApp();
        my $count = $app->{counter}++;
        my $frame = $app->GetTopWindow;
        my $title = $frame->GetTitle;
        $title =~ s{\d*+$}{$count};
        $frame->SetTitle( $title );
        $kev->Skip if 0 == $count % 4; ## sometimes :P
    }
    

    Also, you call your handler _process_char but you use EVT_KEY_DOWN -- there is an EVT_CHAR just for chars :)

    update: For notebook example replace (in above sample) around $text with

        my $noteb = Wx::Notebook->new( $frame );
        my $text  = Wx::TextCtrl->new( $noteb, -1,"", );
        $noteb->AddPage( $text, "you myst type stuff");
        Wx::Event::EVT_KEY_DOWN( $app,  \&Frobnicate );