Philippe has asked for the wisdom of the Perl Monks concerning the following question:

Hi! I hope I'm asking a stupid question (which would then have an obvious answer...). I've defined a few "bindings" for a Perl::Tk window. I would like them to be simply "KeyPress"-ed type: I run into problems when I try have "sequences": say I have defined callbacks for , <c> and <c><d> (sorry...): so I press and get the callback, but when I press <c><d>, I first get the <c> callback and then <c><d>... Is there a way to reset the event sequence? Thanks! Philippe

Replies are listed 'Best First'.
Re: Tk Multiple Event Binding
by zentara (Cardinal) on Dec 16, 2005 at 13:08 UTC
    This old example may help you. It shows how to use a timer to make a slight delay on the first bind, to wait and see if it's a combo. Your best bet, is just to make your bindings unique, so you don't have to worry about this. Do you really need <c><d>? Why not have <e> do what <c><d> is supposed to do?
    #!/usr/bin/perl use strict; use Tk; # by graff of perlmonks # The way that works is that the initial "button-1" event # will invoke "Tk::after" to schedule a call to "print_me" # after half a second, but a double-button-1 event will # call "print_me" immediately, with a parameter that makes # it behave in a special way. The logic associated with # that special parameter also has to "cancel" the Tk::after # object that had been scheduled by the button-1 event that # was the first half of the double-click. my $after_id; my $mw = MainWindow->new(); $mw->Label(-text => "Type a phrase in the entry box below")->pack(); $mw->Label(-text => "Then click once to print all of it")->pack(); $mw->Label(-text => "Or double-click to print just one word")->pack(); my $ent = $mw->Entry(-width => 25)->pack(); $ent->bind( "<Double-Button-1>", [\&print_me, "word"] ); $ent->bind( "<Button-1>", sub { $after_id = $ent->after( 500, [\&print_me, $ent] ) } ); MainLoop; sub print_me { my ( $widget, $mode ) = @_; my $content = $widget->get(); if ( $mode eq "word" ) { $widget->afterCancel( $after_id ); my $start = $widget->index( 'sel.first' ); my $length = $widget->index( 'sel.last' ) - $start; print "you double-clicked the word: " . substr( $content, $start, $length), $/; } else { print $content,$/; } }

    I'm not really a human, but I play one on earth. flash japh
Re: Tk Multiple Event Binding
by BrowserUk (Patriarch) on Dec 16, 2005 at 10:42 UTC

    If you call Tk->break from an event handler, it will prevent any further event handlers being called for that event. So, if you call Tk->break at then end of your event handler bound to '<c>', your '<c><d>' event handler will never be called.

    Whether that is the answer to the question you are asking, is as unclear as your question :) Basically, you are unlikely to get good results from bindings that overlap in this way. How would you (or Tk) decide which of your event handlers should be processed?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks a lot for your reply! I was already experimenting with that (but I haven't been very successful yet...). I was somehow assuming that the event already matched would be "cleared" and not further looked up (I've now realised that it's clearly stated in the documentation that it's not!) Philippe
        In case anyone is ever interesting in such a messy thing...

        "Tk->break" is not really the way, as it's actually *another* "sequence" which kicks in...

        The dirty trick of inserting meaningless events (which are not going to be part of any sequence) with "eventGenerate" seems to do it...

        Thanks!

        Philippe