in reply to Tk Menu question.

First of all, don't use numbered variables. Use an array. Then you can use map to generate the anonymous array elements. (Oh, I renamed a few of your variables / functions to something more self-documenting.)

#!/usr/bin/winperl use warnings; use strict; use Tk; my @menu_items = splice @{[get_menu_items()]}, 0, 3; @menu_items = ('None') unless @menu_items; my $mw = MainWindow->new(); $mw->Label(-text => 'Right-click for menu...')->pack(); my $m = $mw->Menu(-tearoff => 0,font => "{arial} 12 {bold}",-menuitems + => [ map { [Button => $_, -command => sub { replace($_) }] } @menu_items ]); $mw->bind("<Button-3>" => sub { $m->Popup(-popover => "cursor",popanch +or => 'nw') }); $mw->focus(); MainLoop; sub get_menu_items { return qw(); # return qw(Foo Bar Baz); # return qw(Foo Bar Baz Quux Zod Wibble); }

The code to populate @menu_items is a little obfuscated, but not terribly. You could break it up into an if-else. *shrug*

bbfu
Black flowers blossom
Fearless on my breath

Replies are listed 'Best First'.
Re: Re: Tk Menu question.
by perl_seeker (Scribe) on Sep 29, 2003 at 08:13 UTC
    Hi:)
    Your code does exactly what I wanted to do! Really cool.
    Thanx a lot.
Re: Re: Tk Menu question.
by perl_seeker (Scribe) on Oct 06, 2003 at 08:03 UTC
    Hi:)
    I missed this out earlier.Consider this bit of code.
    map { [Button => $_, -command => sub { replace($_) }] } @menu_items
    Is there a way to extract the label of that button in the menu, that the user clicks on,e.g. if the user clicks on
    the first button, the label 'Foo', if it is the third button,the label 'Baz', and so on.

    So that we can have a replace function like this:
    sub replace{ my $chosen="Label of button user clicked on"; + $t->insert('sel.first',"$chosen"); $t->delete('sel.first','sel.last'); $t->tagConfigure("rp",-foreground=>"black"); my $r=$t->search(-forwards,"$chosen",'end'); $t->tagAdd("rp","$r","$r wordend"); } 1;
    I need to use a replace function to replace a word marked by the sel tag in a text widget by the label of the menu button.

    Or else is it possible to call three subroutines,each being invoked when a particular menu button is clicked.Earlier
    my code was of the form:
    $m = $top->Menu(-tearoff => 0,font => "{arial} 12 {bold}", -menuitems => [ [Button => "$opt1", -command => \&replace1], [Button => "$opt2", -command => \&replace2], [Button => "$opt3", -command => \&replace3], ] ); sub replace1{ my $chosen1=$menu_items[0]; $t->insert('sel.first',"$chosen1"); $t->delete('sel.first','sel.last'); $t->tagConfigure("rp1",-foreground=>"black"); my $r1=$t->search(-forwards,"$chosen1",'end'); $t->tagAdd("rp1","$r1","$r1 wordend"); } 1; sub replace2{ my $chosen2=$menu_items[1]; ... } 1; sub replace3{ my $chosen3=$menu_items[2]; ... } 1;
    I tried this but it keeps printing only the first label, i.e. "Foo", even when we click on other menu buttons.
    sub replace{ my $chosen="$menu_items[$_]"; print "\nThe selected word:"; print "\n$chosen"; } 1;
    Thanks in advance.
    :)

      Actually, the code I posted is already sending the label to the replace subroutine (that's why it's sub { replace($_) } and not \&replace).

      Just start out your replace sub like this:

      sub replace { my $label = shift; ... }

      bbfu
      Black flowers blossom
      Fearless on my breath

        Hi,
        thanks a lot for your reply.I tried the replace sub like this:
        sub replace{ my $chosen=shift; $chosen= 'none' unless defined $chosen; print "\nThe selected word:"; print "\n$chosen"; } 1;
        I'm getting this as output:
        The selected word: none
        which means the button label is not being sent by the main code to the replace function, is that right? what is the
        problem here?

        Actually I thought that $_ would simply contain the elements of @menu_items sequentially,i.e Foo, Bar,Baz,
        .... Now I take it that clicking on any menu button will call replace($_), where $_ is the label of the button
        on which we click.

        Thanks in advance.
        :)