How to invoke a tkinter menu *itself*

James Stroud jstroud at ucla.edu
Sun Feb 12 17:36:20 EST 2006


Edward K. Ream wrote:
> Hi,
> 
> 
> 
> I've spent a pleasant hour or so trying to bring up a top-level Tk menu at 
> the same spot as it would appear if I had actually clicked the menu.  That 
> is, I want to bring up a menu from the keyboard.
> 
> 
> 
> The problem is computing the x and y args to menu.post.  menu.winfo_x and 
> menu.winfo_rootx are always 0, presumably be cause the menu isn't packed.
> 
> 
> 
> And I haven't been able to use menu.invoke(??) to invoke the menu *itself*. 
> One would think this would be a basic Tk functionality.
> 
> 
> 
> Any ideas?  Thanks.
> 
> 
> 
> Edward
> 
> 
> 
> P.S. Here is my best so far. (It must be run from Leo for the Leo magic to 
> work.)
> 
> 
> 
> import tkFont
> 
> name = 'File' # The menu to be invoked.
> 
> # A list of all of Leo's menus.
> 
> menus = ('File','Edit','Outline','Plugins','Cmds','Window','Help')
> 
> 
> 
> # Compute the *approximate* x offsets of each menu.
> 
> offsets = {} ; n = 0
> 
> for z in menus:
> 
>     menu = c.frame.menu.getMenu(z)
> 
>     fontName = menu.cget('font')
> 
>     font = tkFont.Font(font=fontName)
> 
>     offsets[z] = n
> 
>     # A total hack: sorta works on windows.
> 
>     n += font.measure(z+' '*4)+1
> 
> 
> 
> top = c.frame.top # Leo magic.
> 
> topx,topy = top.winfo_rootx(),top.winfo_rooty()
> 
> menu = c.frame.menu.getMenu(name) # Leo magic.
> 
> menu.post(topx+offsets.get(name,0),topy)
> 
> 
> 
> EKR
> --------------------------------------------------------------------
> Edward K. Ream   email:  edreamleo at charter.net
> Leo: http://webpages.charter.net/edreamleo/front.html
> --------------------------------------------------------------------
> 
> 
> 

Its not obvious what you want to do. If you are going to have a menu at 
all, I think you application would be better served to always have the 
toplevel menu displayed, otherwise, things can get jumpy if the window 
is always repacking. If you want the main menu to be "contextual" you 
can make two different menuas andplay with toplevel.config(menu=onemenu) 
and toplevel.config(menu=anothermenu), etc. If you just want to forget 
the menu, you can toplevel.config(menu=""), you can bring it back again 
with toplevel.config(menu=somemenu), etc. This will be jumpy. If you 
want a menu that pops up on top of a window, you might have to make 
another window with your menu of choice. Or do you want to just bring 
down a cascade menu?



More information about the Python-list mailing list