[Tutor] keeping track of multiple cascading menus in Tkinter?

Alfred Milgrom fredm@smartypantsco.com
Tue Jan 7 17:04:36 2003


Hi:

I wonder if anyone can help me?
I am trying to create some menus dynamically, and I would like to know 
where a cascading menu is coming from.
Since the menus are built dynamically, the final menu choices could be 
coming from any one of a number of parent menu choices, and I can't tell 
which one was chosen.

The problem I have with the built-in menu types is that a menu item can be 
either a command type or a cascading type, but not both.

I have tried to build a cascading menu with a command but no 'menu=' 
option, and that will execute a command to convert it to a normal cascading 
menu, but it closes the menu before conversion (as with normal menu 
choices) so this does not work for me. The relevant parts of this approach are:

self.mFont.add_cascade(label='Font1', command=lambda index=1 : 
self.insertCascade(index))

def insertcascade(self, index):
	self.mFont.entryconfigure(index, menu=self.styleMenu)

Not only do I want to have style options (normal, bold, italics), but also 
size options (10pt, 12pt, etc.) so I don't want to have to create a zillion 
font/style/size menus and commands.

Is there a simple way to keep track of where you are in a series of 
cascading menus?
(Hope this question makes some sense).
Thanks in anticipation,
Fred Milgrom

Here is a simplified version of the code:

from Tkinter import *

class FontChooser:
    def __init__(self, parent=0):
       self.mainWindow = Frame(parent)
       fMenu=Frame(self.mainWindow)
       fMenu.pack(side=TOP,fill=X)

       bFont=Menubutton(fMenu, text="Font")
       bFont.pack(side=LEFT,anchor=W)
       self.mFont = Menu(bFont,tearoff=0)
       self.styleMenu = Menu(bFont, tearoff=0)
       self.styleMenu.add_command(label='Normal')
       self.styleMenu.add_command(label='Bold')
       self.styleMenu.add_command(label='Italic')

       self.mFont.add_command(label='Font0', command=self.font0)
       self.mFont.add_cascade(label='Font1', command=lambda index=1 : 
self.insertCascade(index))
       bFont["menu"]=self.mFont

       self.entry = Entry(self.mainWindow)
       self.entry.insert(0,"Choose a font")
       self.entry.pack(fill=X)

       fOuter = Frame(self.mainWindow, border=1, relief="sunken")
       fButtons = Frame(fOuter, border=1, relief="raised")
       bClear = Button(fButtons, text="Clear",
                       width=8, height=1, command=self.clearText)
       bQuit = Button(fButtons, text="Quit",
                       width=8, height=1, command=self.mainWindow.quit)
       bClear.pack(side="left", padx=15, pady=1)
       bQuit.pack(side="right", padx=15, pady=1)
       fButtons.pack(fill=X)
       fOuter.pack(fill=X)
       self.mainWindow.pack()
       self.mainWindow.master.title("Font chooser")

    def clearText(self):
       self.entry.delete(0,END)

    def display (self, text) :
       self.clearText()
       self.entry.insert(END, text)

    def font0(self):
        self.display('Font 0 chosen')

    def insertCascade(self, index):
       self.display("Font 1 chosen")
       self.mFont.entryconfigure(index, menu=self.styleMenu)

app = FontChooser()
app.mainWindow.mainloop()