in reply to Multi-column Tk:Optionmenu?

If I were you, I would forget about trying to hack the Optionmenu, and just make your own menu. For instance, just make an icon in your app (or bind to the pointer location to have it open wherever you click), and when you click it, it opens a toplevel window containing whatever multicolumn widget you want. Persoanlly I would use a Canvas and write columns of text to it, tagging each text item to call an appropriate subroutine. Otherwise, you can search for examples of "Cascading menus". Hacking Tk menus can be daunting, there are alot of unamed AoA's nestled in them, and they are bears to figure out. It is easier to make your own, if you want alot of customization. See $menu->insert problem in Perl/Tk for an idea of how tricky it gets.

But someone else may come up with an easy answer for you..... thats the way it goes with Perl/Tk. :-)


I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Replies are listed 'Best First'.
Re^2: Multi-column Tk:Optionmenu?
by BernieC (Pilgrim) on Nov 04, 2007 at 20:56 UTC
    Thanks for the suggestion! I'm relatively new to Tk (I'm a very long time Perl and CGI hacker moving over to using Tk), and there are lots of chunks of Tk I'm not really familiar with (hell, that I barely know anything about..:o)). Canvas is one such, but it looks like it'd make for a simple solution for exactly what I want. Not to mention a VERY handy widget to have in my arsenal... So thanks again!
      I've looked at the Canvas widget and it is definitely a good thing for me to have in my Tk arsenal, but it feels wrong for this application. But the approach got me thinking and wouldn't this work: I'll have a button that pops open a new TopLevel, and I'll just populate the TopLevel with *radiobuttons*. no need that I can see for an intermediary layer of widgets. Just a simple loop with packing a frame into the TL, then packing *it* with radio buttons in for as long as a max-length column should be, then another frame, more radiobuttons, until I run out. They'll all store their value into the same var and have the same callback to deal with the menu selection. [I'd post sample code, but: 1) not written yet, and 2) it seems simple enough that I can't imagine it won't do what I need (or be all that difficult)). It's feeling like about five lines of Perl to do..:o) Am I missing something or is it really the case that this simple approach will get me what I was looking for?
        Your radiobutton solution sounds pretty good. I usually go for the canvas because it can be made to look good, since a common complaint about Tk is it looks drab. My idea was to make a table of rectangles, and put each choice in a rectangle, which changes colors as the mouse passes over it. It's probably more eye candy than you need.

        Just for your advancement, Gtk2 has a nice multicolumn select-drop-down widget.


        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
        SUCCESS!!! (except for making it modal. I looked at the code in Show that handles modal-ness and my eyes kind of glazed over ... any insight into how that stuff works would be appreciated! :o)) The following does pretty much just what I wanted. Only slight problem is where the TL pops up -- a little more research in how how the PopUp stuff handles "make the thing pop up HERE" and I think I've got what I was looking for!

        Meta question: is this worth cleaning up and turning into a real widget, or should I just go back into my hole and use it for my app?
        #!/usr/bin/perl # Test to see if we can make our own multi-column menu out of ## a toplevel and radiobuttons use strict ; use warnings ; use Tk ; my $mw = MainWindow->new ; $mw->Button(-text => "Make menu", -command => \&GenMenu)->pack ; my $picked ; $mw->Entry(-state => 'disabled', -textvariable => \$picked)->pack ; MainLoop() ; my $menuselect ; my $TL ; sub GenMenu { $TL = $mw->Toplevel ; for my $f (1 .. 3) { my $frame = $TL->Frame->pack(-side => 'left'); for my $menu (1 .. 5) { Radio($frame, "Column $f, Row $menu", $f*5 + $menu) ; } } $TL->focus ; } sub PickedMenu { $picked = "You picked entry $menuselect" ; $TL->destroy ; } sub Radio { $_[0]->Radiobutton(-text => $_[1], -value => $_[2], -variable => \$menuselect, -indicatoron => undef, -command => \&PickedMenu)->pack(-fill => 'x') ; }