How to invoke a tkinter menu *itself*

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Edward K. Ream

    #1

    How to invoke a tkinter menu *itself*

    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_root x 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','Plug ins','Cmds','Wi ndow','Help')



    # Compute the *approximate* x offsets of each menu.

    offsets = {} ; n = 0

    for z in menus:

    menu = c.frame.menu.ge tMenu(z)

    fontName = menu.cget('font ')

    font = tkFont.Font(fon t=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_ro oty()

    menu = c.frame.menu.ge tMenu(name) # Leo magic.

    menu.post(topx+ offsets.get(nam e,0),topy)



    EKR
    --------------------------------------------------------------------
    Edward K. Ream email: edreamleo@chart er.net
    Leo: http://webpages.charter.net/edreamleo/front.html
    --------------------------------------------------------------------



  • Edward K. Ream

    #2
    Re: How to invoke a tkinter menu *itself*

    > I've spent a pleasant hour or so trying to bring up a top-level Tk menu at[color=blue]
    > 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.[/color]

    I'm going to investigate how to locate the 'button' that forms the anchor
    for the menu. This button *is* (or should be) packed (or placed), so it
    should know its own location.

    Anyone know how to do find a menu's button?

    Edward
    --------------------------------------------------------------------
    Edward K. Ream email: edreamleo@chart er.net
    Leo: http://webpages.charter.net/edreamleo/front.html
    --------------------------------------------------------------------


    Comment

    • James Stroud

      #3
      Re: How to invoke a tkinter menu *itself*

      Edward K. Ream wrote:[color=blue]
      > 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_root x 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','Plug ins','Cmds','Wi ndow','Help')
      >
      >
      >
      > # Compute the *approximate* x offsets of each menu.
      >
      > offsets = {} ; n = 0
      >
      > for z in menus:
      >
      > menu = c.frame.menu.ge tMenu(z)
      >
      > fontName = menu.cget('font ')
      >
      > font = tkFont.Font(fon t=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_ro oty()
      >
      > menu = c.frame.menu.ge tMenu(name) # Leo magic.
      >
      > menu.post(topx+ offsets.get(nam e,0),topy)
      >
      >
      >
      > EKR
      > --------------------------------------------------------------------
      > Edward K. Ream email: edreamleo@chart er.net
      > Leo: http://webpages.charter.net/edreamleo/front.html
      > --------------------------------------------------------------------
      >
      >
      >[/color]

      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=anotherme nu), 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?

      Comment

      Working...