in reply to Deleting Menu Item from Menu

Update: It seems someone found the way above..way to go. I'll leave my post in here, in case you want to try and add stuff back in, as the $Btn1->parentMenu->delete(0); just lops off the first entry, and dosn't remove an entry by name( actually modifying the underlying AoA is still shrouded in mystery)

See Tk menus

I'm sorry I can't be of more help, but as the "hell" in the url suggests, Tk menus are a mess of deeply nested AoA's which are nearly impossible to access. See $menu->insert problem in Perl/Tk for an example of the complicated syntax needed to get into the nested data structure.

I tried the $mbar->delete(2,1) syntax, and the best it does is destroy the cascade temporarily, but not permanently. Even if you could acess them, I don't know if you can delete menuitems once they are created. You may need to destroy the entire menu, and rebuild a new one. Usually, you just see items "greyed out", like

#!/usr/bin/perl use warnings; use strict; use Tk; my $count = 0; my $mw = tkinit; my $menubar = $mw->Menu(-type => 'menubar'); $mw->configure(-menu => $menubar); my $menu = $menubar->cascade(-label => '~File'); $menu->command(-label => '~New'); $menu->command(-label => '~Open'); my $menu1 = $menubar->cascade(-label => '~Test'); $menu1->command(-label => '~Yee'); $menu1->command(-label => '~Haw'); $mw->Button( -text => 'Push me and look at the menu', -command => sub { my $state = ($count++ & 1) ? 'normal' : 'disabled'; $menu->cget(-menu)->entryconfigure(2, -state => $state); $menu1->cget(-menu)->entryconfigure(2, -state => $state); } )->pack; MainLoop;

You may find it easier just to switch menus, like

#!/usr/bin/perl use warnings; use strict; use Tk; my $top = MainWindow->new; $top->geometry('200x100'); my $text; my $top_label = $top->Label( -textvariable => \$text )->pack; my $menu = $top->Menu( -type => 'menubar', -tearoff => 0 ); $top->configure( -menu => $menu ); my %menucommand = ( Save => { cmd => [ \&callback, 'Save' ], acc => 'Ctrl+S' }, 'Save As' => { cmd => [ \&callback, 'Save As' ], acc => 'Ctrl+A' }, ASCII => { cmd => [ \&callback, 'ASCII' ] }, Hex => { cmd => [ \&callback, 'Hex' ] }, Binary => { cmd => [ \&callback, 'Binary' ] }, Open => { cmd => [ \&callback, 'Open' ] }, Close => { cmd => [ \&callback, 'Close' ] }, Exit => { cmd => [ \&callback, 'Exit' ] }, Enter => { cmd => [ \&callback, 'Enter' ] }, 'Go Nuts' => { cmd => [ \&callback, 'Go Nuts' ] }, Quit => { cmd => [ \&callback, 'Quit' ], acc => 'Ctrl+Q' }, Stop => { cmd => [ \&callback, 'Stop' ] }, Go => { cmd => [ \&callback, 'Go' ] }, Up => { cmd => [ \&callback, 'Up' ] }, Down => { cmd => [ \&callback, 'Down' ] }, ); addmenu( $menu, 'Save', 'Save', 'Save As', 'Quit' ); addmenu( $menu, 'Show source', qw/ASCII Hex Binary/ ); addmenu( $menu, 'Default Menu', '' ); $top->Button( -text => 'This menu', -command => sub { $menu->delete('end'); addmenu( $menu, 'This menu', qw/Enter Exit Stop Go/ ); } )->pack; $top->Button( -text => 'That menu', -command => sub { $menu->delete('end'); addmenu( $menu, 'That menu', qw/Up Down Quit/, 'Go Nuts' ); } )->pack; MainLoop; sub callback { $text = "$_[0] was chosen!"; } sub addmenu { my ( $menu, $label, @options ) = @_; my $sub_menu = $menu->cascade( -label => $label, -tearoff => 0 ); for my $option (@options) { next unless defined $menucommand{$option}; $sub_menu->command( -label => $option, -command => $menucommand{$option}{cmd}, -accelerator => $menucommand{$option}{acc} || '', ); } }

I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^2: Deleting Menu Item from Menu
by Anonymous Monk on Jan 28, 2009 at 15:59 UTC
    .. just lops off the first entry, and dosn't remove an entry by name( actually modifying the underlying AoA is still shrouded in mystery)
    To reveal some, try $Btn1->[0]->delete(); errors
    Tk::Error: wrong # args: should be ".menu.main.insert delete first ?la +st?" at D:/Perl/site/lib/Tk.pm line 247. Tk callback for .menu.main.insert (menu invoke)
    Curious. To look up the name you need
    $Btn1->parentMenu->delete($Btn1->parentMenu->index($Btn1->[1])); # or $Btn1->[0]->delete($Btn1->[0]->index($Btn1->[1])); # or $$Btn1[0]->delete($$Btn1[0]->index($$Btn1[1])); # or $insert->menu->delete($insert->menu->index($$Btn1[1]));
    Yucky :)
      Here is a way to add to the menu
      sub add_menu{ # must be cascade, checkbutton, command, radiobutton, or separator $Btn1->parentMenu->add('command',-label => time, -command=>sub{print "3\n";}); }

      I'm not really a human, but I play one on earth Remember How Lucky You Are
      Thanks for that insight, every bit helps. It would be sweet to have a menuing system that used a tied AoH ( or similar) to build the menu, then have it automatically adjust to changes in the tied structure.

      I'm not really a human, but I play one on earth Remember How Lucky You Are