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

The Tk::BrowseEntry widget has a flaw: it overrides the binding for "<ButtonRelease-1>" in its main window. Here is some example code:
use strict; use Tk; sub gotClick { print "got click\n"; } my $main = new MainWindow; # This one gets wiped out. $main->bind('<ButtonRelease-1>' => sub { gotClick() }); my $combo = $main->BrowseEntry(); $combo->pack(); Tk::MainLoop();
The problem appears to be here:
BrowseEntry.pm:78: $b->toplevel->bind('<ButtonRelease-1>',[$w,'Bu +ttonHack']);

My temporary work-around is to do the window's event binding last, after all the controls have been created. Is there a better way to get around this problem?

Replies are listed 'Best First'.
Re: Tk::BrowseEntry eats click binding
by Tanalis (Curate) on Jan 22, 2003 at 08:59 UTC
    I think you've found the simplest way around the problem.

    Looking into the module's code, the binding is done deliberately, although it seems fairly safe to remove.

    If you go into the subs (note that line 104 also calls the ButtonHack sub), you'll see the following:

    # This hack is to prevent the ugliness of the arrow being depressed. # sub ButtonHack { my ($w) = @_; my $b = $w->Subwidget('arrow'); if ($w->{'buttonHack'}) { $b->butUp; } }
    So, from that, it seems a purely cosmetic thing, and isn't (shouldn't be) critical to the operation of the widget at all.

    Of course, I don't know how ugly the depressed arrow button is *grin* .. maybe that's a factor.

    I definitely need to point out I haven't tested this, at all, it's based on looking through the module's source code. I also wouldn't even think about changing the module's code, unless it's completely necessary.

    I'd suggest that the hack round the problem that you've already found and are using already is probably the best way to go. That'll certainly be the simplest and easiest-to-implement solution, not to mention helping when it comes to the future maintaining of the script.

    Hope that helps ..
    -- Foxcub

    Random Note: It's taken a long while to get here, but this is my 100th post. Roll on 1000 ...

Re: Tk::BrowseEntry eats click binding
by castaway (Parson) on Jan 22, 2003 at 08:55 UTC
    Umm.. according to 'man Tk::Widget',
    $widget->toplevel Returns the reference of the top-level window containing $w +idget.
    Which sounds to me like your $b->toplevel->bind .. is binding to the MainWindow that the BrowseEntry is in, eg. your $main widget. I'm assuming $b is your BrowseEntry Widget, which you don't say.
    Why not just do  $combo->bind( .. ) to add a ButtonRelease to your BrowseEntry widget?

    Apologies if I've understood this wrong, please post the rest of the code so we can see what its doing.

    C.

      ...please post the rest of the code so we can see what its doing.

      The example program I posted is complete. It just shows that the binding is overridden. You can try it by running the program and clicking on the window -- no callback. If you move the binding to after the lines where the BrowseEntry is created, the callback will work.

      The second one-line snippet is from the Tk::BrowseEntry code itself, which is on CPAN.