Long Tkinter Menu

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dustan

    #1

    Long Tkinter Menu

    I don't know if this is because of Tkinter (ie Tk) itself or the
    Windows default way of handling things, but when I create a very long
    menu (my test is shown below), the way it displays is rather sucky; the
    menu stretches from the top of the moniter's window to the bottom (no
    matter the size of the actual application).

    Is there any alternative format for how a long menu gets displayed? It
    would be nice if say, I could make the menu only go to the borders of
    the application itself (in this case, not that long).

    As for why I'm creating such a long menu, think browser bookmarks
    (That's not actually what I'm doing, but similar).

    =============== =============== ==
    # menu-example-5.py

    from Tkinter import *

    root = Tk()

    menubar = Menu(root)

    menu = Menu(menubar, tearoff=0)
    for i in xrange(100):
    menu.add_comman d(label=str(i), command=root.qu it)
    menu.add_comman d(label="Exit", command=root.qu it)

    menubar.add_cas cade(label="Tes t", menu=menu)

    root.config(men u=menubar)

    mainloop()
    =============== =============== ==

  • Eric Brunel

    #2
    Re: Long Tkinter Menu

    On Thu, 05 Oct 2006 02:33:54 +0200, Dustan <DustanGroups@g mail.comwrote:
    I don't know if this is because of Tkinter (ie Tk) itself or the
    Windows default way of handling things, but when I create a very long
    menu (my test is shown below), the way it displays is rather sucky; the
    menu stretches from the top of the moniter's window to the bottom (no
    matter the size of the actual application).
    >
    Is there any alternative format for how a long menu gets displayed? It
    would be nice if say, I could make the menu only go to the borders of
    the application itself (in this case, not that long).
    To limit the menu in the application window, will be difficult. But here
    are two ways of automatically limiting the number of entries that can
    appear in a menu by specializing the Tkinter Menu class:

    ------------------------------------------------------
    from Tkinter import *

    class LongMenu(Menu):
    """
    Automatically creates a cascade entry labelled 'More...' when the
    number of entries is above MAX_ENTRIES.
    """

    MAX_ENTRIES = 20

    def __init__(self, *args, **options):
    Menu.__init__(s elf, *args, **options)
    self.nextMenu = None

    def add(self, itemType, cnf={}, **kw):
    if self.nextMenu is not None:
    return self.nextMenu.a dd(itemType, cnf, **kw)
    nbEntries = self.index(END)
    if nbEntries < LongMenu.MAX_EN TRIES:
    return Menu.add(self, itemType, cnf, **kw)
    self.nextMenu = LongMenu(self)
    Menu.add(self, 'cascade', label='More...' , menu=self.nextM enu)
    return self.nextMenu.a dd(itemType, cnf, **kw)


    class AutoBreakMenu(M enu):
    """
    Automatically adds the 'columnbreak' option on menu entries to make
    sure that the menu won't get too high.
    """

    MAX_ENTRIES = 20

    def add(self, itemType, cnf={}, **kw):
    entryIndex = 1 + (self.index(END ) or 0)
    if entryIndex % AutoBreakMenu.M AX_ENTRIES == 0:
    cnf.update(kw)
    cnf['columnbreak'] = 1
    kw = {}
    return Menu.add(self, itemType, cnf, **kw)



    if __name__ == '__main__':
    root = Tk()

    menubar = Menu(root)

    def fillMenu(menu):
    for i in xrange(100):
    menu.add_comman d(label=str(i), command=root.qu it)
    menu.add_comman d(label="Exit", command=root.qu it)

    menu1 = LongMenu(menuba r, tearoff=0)
    fillMenu(menu1)
    menu2 = AutoBreakMenu(m enubar, tearoff=0)
    fillMenu(menu2)

    menubar.add_cas cade(label="Tes t1", menu=menu1)
    menubar.add_cas cade(label="Tes t2", menu=menu2)

    root.config(men u=menubar)

    root.mainloop()
    ------------------------------------------------------

    If your application is more complicated than that (e.g if you insert menu
    entries after the first adds), you'll have to change the code above a bit,
    since it doesn't handle calls to insert at all. But you get the idea.

    HTH
    --
    python -c "print ''.join([chr(154 - ord(c)) for c in
    'U(17zX(%,5.zmz 5(17l8(%,5.Z*(9 3-965$l7+-'])"

    Comment

    • Dustan

      #3
      Re: Long Tkinter Menu


      Eric Brunel wrote:
      On Thu, 05 Oct 2006 02:33:54 +0200, Dustan <DustanGroups@g mail.comwrote:
      >
      I don't know if this is because of Tkinter (ie Tk) itself or the
      Windows default way of handling things, but when I create a very long
      menu (my test is shown below), the way it displays is rather sucky; the
      menu stretches from the top of the moniter's window to the bottom (no
      matter the size of the actual application).

      Is there any alternative format for how a long menu gets displayed? It
      would be nice if say, I could make the menu only go to the borders of
      the application itself (in this case, not that long).
      >
      To limit the menu in the application window, will be difficult. But here
      are two ways of automatically limiting the number of entries that can
      appear in a menu by specializing the Tkinter Menu class:
      >
      ------------------------------------------------------
      from Tkinter import *
      >
      class LongMenu(Menu):
      """
      Automatically creates a cascade entry labelled 'More...' when the
      number of entries is above MAX_ENTRIES.
      """
      >
      MAX_ENTRIES = 20
      >
      def __init__(self, *args, **options):
      Menu.__init__(s elf, *args, **options)
      self.nextMenu = None
      >
      def add(self, itemType, cnf={}, **kw):
      if self.nextMenu is not None:
      return self.nextMenu.a dd(itemType, cnf, **kw)
      nbEntries = self.index(END)
      if nbEntries < LongMenu.MAX_EN TRIES:
      return Menu.add(self, itemType, cnf, **kw)
      self.nextMenu = LongMenu(self)
      Menu.add(self, 'cascade', label='More...' , menu=self.nextM enu)
      return self.nextMenu.a dd(itemType, cnf, **kw)
      >
      >
      class AutoBreakMenu(M enu):
      """
      Automatically adds the 'columnbreak' option on menu entries to make
      sure that the menu won't get too high.
      """
      >
      MAX_ENTRIES = 20
      >
      def add(self, itemType, cnf={}, **kw):
      entryIndex = 1 + (self.index(END ) or 0)
      if entryIndex % AutoBreakMenu.M AX_ENTRIES == 0:
      cnf.update(kw)
      cnf['columnbreak'] = 1
      kw = {}
      return Menu.add(self, itemType, cnf, **kw)
      >
      >
      >
      if __name__ == '__main__':
      root = Tk()
      >
      menubar = Menu(root)
      >
      def fillMenu(menu):
      for i in xrange(100):
      menu.add_comman d(label=str(i), command=root.qu it)
      menu.add_comman d(label="Exit", command=root.qu it)
      >
      menu1 = LongMenu(menuba r, tearoff=0)
      fillMenu(menu1)
      menu2 = AutoBreakMenu(m enubar, tearoff=0)
      fillMenu(menu2)
      >
      menubar.add_cas cade(label="Tes t1", menu=menu1)
      menubar.add_cas cade(label="Tes t2", menu=menu2)
      >
      root.config(men u=menubar)
      >
      root.mainloop()
      ------------------------------------------------------
      >
      If your application is more complicated than that (e.g if you insert menu
      entries after the first adds), you'll have to change the code above a bit,
      since it doesn't handle calls to insert at all. But you get the idea.
      >
      HTH
      --
      python -c "print ''.join([chr(154 - ord(c)) for c in
      'U(17zX(%,5.zmz 5(17l8(%,5.Z*(9 3-965$l7+-'])"
      Thanks, I'll see what I can do with that.

      Comment

      Working...