Long Tkinter Menu
Dustan
DustanGroups at gmail.com
Thu Oct 5 06:28:35 EDT 2006
Eric Brunel wrote:
> On Thu, 05 Oct 2006 02:33:54 +0200, Dustan <DustanGroups at gmail.com> wrote:
>
> > 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__(self, *args, **options)
> self.nextMenu = None
>
> def add(self, itemType, cnf={}, **kw):
> if self.nextMenu is not None:
> return self.nextMenu.add(itemType, cnf, **kw)
> nbEntries = self.index(END)
> if nbEntries < LongMenu.MAX_ENTRIES:
> return Menu.add(self, itemType, cnf, **kw)
> self.nextMenu = LongMenu(self)
> Menu.add(self, 'cascade', label='More...', menu=self.nextMenu)
> return self.nextMenu.add(itemType, cnf, **kw)
>
>
> class AutoBreakMenu(Menu):
> """
> 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.MAX_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_command(label=str(i), command=root.quit)
> menu.add_command(label="Exit", command=root.quit)
>
> menu1 = LongMenu(menubar, tearoff=0)
> fillMenu(menu1)
> menu2 = AutoBreakMenu(menubar, tearoff=0)
> fillMenu(menu2)
>
> menubar.add_cascade(label="Test1", menu=menu1)
> menubar.add_cascade(label="Test2", menu=menu2)
>
> root.config(menu=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.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
Thanks, I'll see what I can do with that.
More information about the Python-list
mailing list