in reply to Tk event bindings - single vs. double click
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.#!/usr/bin/perl use strict; use Tk; 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 confess that it seems a bit unappealing. For one thing, I haven't figured out how to do this without, in effect, declaring a global $after_id variable (so that I can cancel the "after" object from a callback); for another, I dislike the idea of making the user wait at all for a response to a single-click, even just half a second. (Maybe the delay could be "optimized" if you can figure out or control the maximum interval that defines the double-click.)
The only other choice I can think of would be to abandon hope for the "intuitive" use of single- versus double-click, and adapt to using two truly distinct events, like "button-1" versus "shift-button-1" or "button-3" or something like that.
update: I fixed and rearranged the alternative event choices in the last paragraph, to make more sense. Also, in case the syntax of the two bind calls seems odd, I wanted to explain that, in the first case, bind will automatically provide the widget handle that receives the event as the first parameter to the referenced callback, so any other parameters provided in the bind call ("word", in this case) will be placed in "@_" after the widget handle. In the second "bind", I'm calling "print_me" from within an anonymous sub, so I have to pass the widget handle explicitly myself.
another update: (making multiple updates is one of my characteristic sins...) If you do decide to use "button-3" instead of double-click for your second event, you can have both events bind to the same callback sub, and include Ev('b') as one of the paramaters passed to it -- this will tell the callback which button was pressed. (I'm not sure how to tell it about a modified event like "shift-button-1" vs. an unmodified "button-1".)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Tk event bindings - single vs. double click
by eserte (Deacon) on May 10, 2004 at 09:43 UTC |