I try to modify an existing program, which currently initializes
statically a menu hierarchy.
I'd like to defer this to later.
Here is a code snippet (complete and running, even if stupid), which
shows my (wrong) expectation:
-8<-------------
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
$mw->optionAdd('*Menu.tearOff',0);
$mw->optionAdd('*Menu.font','Arial 12 bold');
my $frame = $mw->Frame(-width => 200, -height => 240)->pack;
my $but = $frame->Menubutton(-text => 'Foo', -underline => 0)->pack(-
side => 'left');
my $menu = $but->Menu(-tearoff => 'false');
$but->configure(-menu => $menu);
my $sub = $menu->Menu(-tearoff => 'false');
$menu->add('cascade', -label =>'Bar', -command => \&foo, -menu =>
$sub);
$menu->postcascade(0);
$sub->add('radiobutton', -label =>'Zoo');
MainLoop;
sub foo {
print "foo\n";
}
-8<------------------
It defines one button, labelled 'Foo', from which opens a menu, with
one entry 'Bar', from which opens a cascading menu, with now only a
radio button, 'Zoo'.
I'd like to create the list of radio buttons only as late as possible,
i.e. just before posting the menu.
I thought this would happen by registering a 'foo' command callback,
but this one is never invoked.
So my questions:
- why isn't it invoked?
- how should I register it instead of how I do?
- is my idea otherwise bad, and if so why?
Thanks,
Marc
-command is used in Menus to indicate a callback executed when a
selection is made within the menu.
-postcommand is a callback that is made just before the menu is
posted
which is what you're looking for. Not sure whether
you can make changes to the menu this late, but I don't see anything
that says you can't.
I've never tried what you're doing so I don't know if it will work.
You could also try using a regular button which when pressed generates
the menu that you want and displays it. Good luck.
> -command is used in Menus to indicate a callback executed when a
> selection is made within the menu.
>
> -postcommand is a callback that is made just before the menu is
> posted which is what you're looking for. Not sure whether
> you can make changes to the menu this late, but I don't see anything
> that says you can't.
Thanks!
I was looking at the wrong spot in the Tk::Menu pod/man page:
CASCADE ENTRIES
...
If a -command option is specified for a cascade entry then it
is
evaluated whenever the entry is invoked. This is not supported
on
Windows.
postcommand is an option at Menu creation:
WIDGET-SPECIFIC OPTIONS
Name: postCommand
Class: Command
Switch: -postcommand
There it works!
Thanks.
Marc
> There it works!
I am not quite done with my change, and again stuck.
Now that I do not create all the sub menus in advance,
I could have only one shared stub.
Only, is there a way for to know which cascade menu it was invoked
from?
Again my small, modified demo:
-8<----
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
$mw->optionAdd('*Menu.tearOff',0);
$mw->optionAdd('*Menu.font','Arial 12 bold');
my $frame = $mw->Frame(-width => 200, -height => 240)->pack;
my $but = $frame->Menubutton(-text => 'Foo', -underline => 0)->pack(-
side => 'left');
my $menu = $but->Menu(-tearoff => 'false');
$but->configure(-menu => $menu);
my $sub = $menu->Menu(-tearoff => 'false', -postcommand => \&foo);
for (qw(Apple Orange Banana)) {
$menu->add('cascade', -label =>$_, -menu => $sub);
}
$menu->postcascade(0);
my $i = 0;
MainLoop;
sub foo {
$i++;
$sub->delete(0, 0);
$sub->add('command', -label =>"Zoo $i");
}
-8<-----------
In foo, I would of course add different sets of options for the
various fruits.
I am stuck in my actual code (couldn't so far narrow down what
interfers) with what looks like a stack corruption. I.e. the
equivalent variable for $i gives something very strange.
I tried to debug this (with perl -d) but only to notice that Tk and DB
both claim the same 'caller' so that my breakpoints just hang...
Are there known recipes for this kind of woes?
Oops... I didn't search the FAQ for that answer...
Thanks,
Marc
> I am stuck in my actual code (couldn't so far narrow down what
> interfers) with what looks like a stack corruption. I.e. the
> equivalent variable for $i gives something very strange.
I got this one!
I was passing an argument to the callback, and expecting it would be
evaluated at definition time:
my $n = 2;
my $sub = $menu->Menu(-tearoff => 'false', -postcommand =>
sub{foo($n)});
But now, I know even only the /address/ of $n is actually used there.
My other two questions remain.
Thanks,
Marc
> My other two questions remain.
OK, one more.
How do I empty a menu?
There is a delete function which takes a range, but how do I know the
lenght?
Do I have to record it myself?
Marc
A new question should be in a new post, not a reply to a different question.
Index doesn't have to be a number. Check perldoc Tk::Menu
in the section titled WIDGET METHODS
delete(0, 'end')
> Index doesn't have to be a number. Check perldoc Tk::Menu
> in the section titled WIDGET METHODS
>
> delete(0, 'end')
Thanks. Taken into use. Works well.
I cannot see how I missed it... I thought it was only for text
entries...
Marc