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

Been stressing around in the docs trying to find out how we can place an image in menuitems (on menubar, e.g. "File"-menu etc) to the far left (like other apps do).

Starting to wonder if this is even possible?

#!/usr/bin/perl -w use Tk; use Tk::Compound; use strict; my $mw = tkinit; my $compound = $mw->Compound; #How do we place this image to far left in menu? $compound->Bitmap(-bitmap => 'question', -anchor=>'w'); $compound->Space(-width => 8); $compound->Text(-text => "Open", -underline => 0); my $menubar = $mw->Menu(-type => 'menubar', ); my $menuitem = [ [command => Open, -image => $compound] ]; $menubar->cascade(-label => 'File',-tearoff => 0, -menuitems => $m +enuitem); $mw->configure(-menu => $menubar); MainLoop;

Update:Removed unnecessary usage of Tk::ToolBar.

Replies are listed 'Best First'.
Re: Placement of image with Tk::Compound and Tk::Menu
by jdtoronto (Prior) on Jul 05, 2006 at 03:29 UTC
    If you read the docs on Tk::Menu under image you will see:
    -image => value Specifies an image to display in the menu instead of a text string + or bitmap The image must have been created by some previous invocati +on of image create. This option overrides the -label and -bitmap opti +ons but may be reset to an empty string to enable a textual or bitmap + label to be displayed. This option is not available for separator or + tear-off entries.
    Telling you to go look at the Tk::Image module to create the image.

    If you want to use the 'images' from the Tk::Toolbar I think you will have to use the -bitmap option on the menu item rather than -image.

    In addition, you have not used a geometry manager on your widgets in the code you showed us, so you wouldn't see anything anyway! Even the very simple example in Tk::Compound will give you some clues:

    my $b = $parent->Button; my $c = $b->Compound; $b->configure(-image => $c); $c->Line; $c->Bitmap(-bitmap => 'warning'); $c->Space(-width => 8); $c->Text(-text => "Warning", -underline => 0); $b->pack;

    jdtoronto

      Do you know Tk::Compound?

      It makes it possible to combine text and image and is a way to create menuitmes with both images and text in perl/Tk.

      Problem is how can I place image to far left in menu (left justify it, that is)?

        Yes, the answer is GEOMETRY MANAGER.
        #!/usr/bin/perl -w use strict; use Tk; use Tk::Compound; my $parent = MainWindow->new(); my $b = $parent->Button; my $c = $b->Compound; $b->configure(-image => $c); $c->Line; $c->Bitmap(-bitmap => 'warning'); $c->Space(-width => 8); $c->Text(-text => "Warning", -underline => 0); $b->pack(-side => 'left'); MainLoop();
        This is the example code from Tk::Compound's documentation with a couple of things added to make it runnable. Note the addition of  -side => 'left' as an option to the pack command. Tk::pack is not my genoetry manager of choice, but it is simple for this demonstration. I would suggest developing amore than nodding acquaintance with "Mastering Perl/Tk" by Lidie and Walsh, published by O'Reilly.

        jdtoronto

Re: Placement of image with Tk::Compound and Tk::Menu
by GrandFather (Saint) on Jul 05, 2006 at 04:06 UTC

    Just to make it absolutly clear: you do you mean you want to associate an icon or bitmap with the top level menu entrys ('File' in your sample) don't you?


    DWIM is Perl's answer to Gödel
      Thanks for the replies, I appreciate it.

      Sorry I might have been unclear in my explanation.

      The sample code works just as I want it to work, the only problem is placement of image in the "Open" menuitem, located under "File" on the menubar. I want image (bitmap) to be located to far left then followed by text.

      The way the code works now the image is displayed where the text would go if no image was used at all and we get big empty space to the left of image, like this (- is space, I is image):

      File
      -----I--open

      I want:

      File
      I--open

      Just like every other normal program. Hm, is this understandable?

        Ok, understood. If I change items to:

        my $menuitem = [ [command => 'Open', -image => $compound], [comman +d => 'close'] ];

        Then the left edge of the ? lines up with the left edge of close - that is, there is only as much space to the left of either entry as I would expect. Indeed, if I add an edit menu with two plain entries:

        $menuitem = [ [command => 'Open'], [command => 'close'] ]; $menubar->cascade(-label => 'Edit', -tearoff => 0, -menuitems => $ +menuitem);

        I see the same amount of space to the left of the entries there.

        However, I can see your issue - the space to the left is excessive and other programs are capable of putting an icon there. Problem understood. :) No answer yet, but I'll look into it later tonight if you haven't an answer before then.


        DWIM is Perl's answer to Gödel
Re: Placement of image with Tk::Compound and Tk::Menu
by ldln (Pilgrim) on Jul 05, 2006 at 20:21 UTC
    Ok, so this is what I have: We can use the -hidemargin to force image in menuitem (using Tk::Compound) to the far left.

    There are two major problems left:

    1) Image used in menuitem does not appear properly before it is hoovered over by mouse pointer.
    2) "Hook" of checkbutton now has disappeared. Where did it go?

    Example code demoonstrates these issues.

    #!/usr/bin/perl -s use Tk; use Tk::ToolBar; use Tk::Compound; use strict; my $mw = MainWindow->new(); #Load images from Tk::ToolBar. my $tb = $mw->ToolBar(); $tb->destroy(); my $compound = $mw->Compound; $compound->Image( -image => 'acthelp16', -anchor => 'w' ); $compound->Space( -width => 8 ); $compound->Text( -text => "Open", -underline => 0 ); $compound->Space( -width => 28 ); my $menubar = $mw->Menu( -type => 'menubar', ); my $c2 = $mw->Compound; $c2->Space(-width => 40); $menubar->cascade( -label => 'File', -tearoff => 0, -menuitems => [ #Problem 1: Image is now shown properply before we #hoover over menuitem. [ Command => 'Open', -image => $compound, -hidemargin => 1, ] +, '-', #Problem2: When we are using hidemargin, the "hook" #of the checkbutton doesn't appear anymore. [ Checkbutton => 'Checkthing', -hidemargin => 1, -image=>$c2, + -compound=>'left', ], ] ); $mw->configure( -menu => $menubar ); MainLoop;
    Update:
    Ok, I've figured this out now. It appears that we have to set up an after timer with -postommand to configure images as menu is shown to get them to display correctly. This is might be bug on win32 only!? Bitmaps seems to display fine without this hack.

    CheckButton indicator is removed when -hidemargins is enabled. Nothing to do about that. Solution for me is to move all CheckButton menuitems to a seperate cascade menu where we turn off -hidemargins and populate with CheckButton menuitems only.

    Update (for later reference):
    Ok, seems like xpm images, created with the Pixmap()-method, work ok with menus on win32. Then we can avoid "-postcommand fix" ,which create ugly flash when many icons are used, and use icons with lots of colors (unlike bitmaps).
    Tools "any to icon"/"icon to any" can convert images to .ico/xpm-files.