Modify Exercise 11.7 so that, as the user adds menus and menu items a sample menu displays and is updated with any new information.
What will be an ideal response?
```
# Menu generation program
from Tkinter import *
from tkMessageBox import *
import Pmw
class MenusList( Frame ):
"""Allow user to view menu items of a selected menu"""
def __init__( self, menus ):
"""Create single-selection list and ScrolledText"""
Frame.__init__( self )
Pmw.initialise()
self.grid( sticky = N+W+E+S )
self.master.title( "View menu items" )
listItems = []
self.menus = menus
# add menu to list
for menu in self.menus:
for key in menu.keys():
listItems.append( key )
# created scrolled list box for menus
self.listBox = Pmw.ScrolledListBox( self, items =
listItems, listbox_height = 5, vscrollmode = "static",
listbox_selectmode = SINGLE, selectioncommand =
self.showMenuItems, label_text = "Menus", labelpos = N )
self.listBox.grid( sticky = W, padx = 10, pady = 10 )
# create scrolled text area for submenus
self.chosen = Pmw.ScrolledText( self, text_height = 6,
text_width = 20, label_text = "Menu Items",
labelpos = N )
self.chosen.grid( sticky = W, padx = 5, pady = 5, row = 0,
column = 2 )
def showMenuItems( self ):
"""Display the menu items in the ScrolledText component"""
self.chosen.clear() # clear contents of chosen
menuName = self.listBox.getcurselection()[ 0 ]
# display each menu
for menu in self.menus:
if menu.has_key( menuName ):
for value in menu.get( menuName ):
self.chosen.insert( END, value + "\n" )
CreateMenu.addMenuEntry.insert( INSERT, menuName )
class CreateMenu( Frame ):
"""Allow user to customize menu and outputs code for the menu"""
def __init__( self ):
"""Create GUI"""
Frame.__init__( self )
Pmw.initialise()
self.grid( sticky = N+W+E+S )
self.master.title( "Creating a Menu" )
self.master.rowconfigure( 0, weight = 1 )
self.master.columnconfigure( 0, weight = 1 )
# list of dictionaries containing menus and their items
self.menuInformation = []
self.menuDemo = 0 # times menu demo has been altered
# beginning of autogenerated menu code
self.code = '''
from Tkinter import *
import Pmw
class AutoMenu( Frame ):
"""Generated menu"""
def __init__( self ):
"""Create a MenuBar with items"""
Frame.__init__( self )
Pmw.initialise()
self.grid( sticky = N+W+E+S )
self.master.title( "Menu" )
self.choices = Pmw.MenuBar( self )
self.choices.grid( sticky = E+W )'''
self.newCode = "" # generated code
self.expression = """"""
self.callbacks = "" # callback definitions
# menu names
self.addMenuLabel = Label( self, text = "Menu Name:" )
self.addMenuLabel.grid( row = 1, column = 1, pady = 10,
sticky = W )
CreateMenu.addMenuEntry = Entry( self )
CreateMenu.addMenuEntry.grid( row = 1, column = 3,
sticky = W+E )
# menu items
self.addItemLabel = Label( self,
text = "Menu Item \nName:" )
self.addItemLabel.grid( row = 3, column = 1, pady = 10,
sticky = W+E )
self.addItemEntry = Entry( self )
self.addItemEntry.grid( row = 3, column = 3, padx = 5,
sticky = W+E )
# callback definitions for menu items
self.definition = Pmw.ScrolledText( self,
text_width = 30, text_height = 12, text_wrap = NONE,
hscrollmode = "static", vscrollmode = "static",
label_text = "Callback Definition", labelpos = N,
borderframe = 1 )
self.definition.grid( row = 5, columnspan = 6,
sticky = E+W )
# add menus and menu items
self.addButton = Button( self, text = "Add", width = 10 )
self.addButton.bind( "
self.addButton.grid( row = 7, column = 1, pady = 10 )
# clear GUI
self.clearButton = Button( self, text = "Clear",
width = 10 )
self.clearButton.bind( "
self.clearButton.grid( row = 7, column = 3, pady = 10 )
# terminate program and output code
self.finishButton = Button( self, text = "Finish",
width = 10 )
self.finishButton.bind( "
self.finishButton.grid( row = 7, column = 5, pady = 10 )
def add( self, event ):
"""Add menus and menu items to a menu"""
# remove list component if it exists
if len( self.menuInformation ) != 0:
self.list.grid_remove()
menuName = self.addMenuEntry.get()
menuItem = self.addItemEntry.get()
callBackDefinition = self.definition.get()
# add menu item with call back
if menuName != "" and menuItem != "" and \
callBackDefinition != "\n":
hasKey = 0
# set hasKey = 1 if menu menuName exists
for menu in self.menuInformation:
if menu.has_key( menuName ):
hasKey = 1
break
# menu menuName does not exist
if not hasKey or len( self.menuInformation ) == 0:
self.newCode += """
self.choices.addmenu( \"""" + menuName + """\", None )"""
self.expression += """
self.choices.addmenu( \"""" + menuName + """\", None )"""
self.menuInformation.append( { menuName: [] } )
self.generateMenu()
functionName = callBackDefinition.split()[ 1 ]
self.newCode += """
self.choices.addmenuitem( \"""" + menuName + """\",
"command", label = \"""" + menuItem + """\", command = """ \
+ functionName[ :-1 ] + """ )"""
self.expression += """
self.choices.addmenuitem( \"""" + menuName + """\",
"command", label = \"""" + menuItem + """\" )"""
self.generateMenu()
# associate menu items with menus
for menu in self.menuInformation:
items = menu.get( menuName )
if items == None:
items = []
items.append( menuItem )
# add callback definition to attribute callbacks
callBackDefinition = callBackDefinition.split( "\n" )
self.callbacks += "\n"
for line in callBackDefinition:
self.callbacks += "\n " + line
# add menu
elif menuName != "" and menuItem == "" and \
callBackDefinition == "\n":
# error: menu already exists
for menu in self.menuInformation:
if menu.get( menuName ) != None:
showerror( "Oops!", "Menu name already exists." )
self.clearGUI( event )
return
self.newCode += """
self.choices.addmenu( \"""" + menuName + """\", None )"""
self.expression += """
self.choices.addmenu( \"""" + menuName + """\", None )"""
self.menuInformation.append( { menuName: [] } )
self.generateMenu()
else:
showerror( "Oops!", "Enter a Menu Name or " + \
"a Menu Name, Item and callback" )
self.clearGUI( event )
return
# clear Entry components and ScrolledText
self.clearGUI( event )
self.list = MenusList( self.menuInformation )
self.code += self.newCode
def finish( self, event ):
"""Terminate program by displaying code to create menu"""
self.list.grid_forget()
self.output = Text( self )
self.code += self.newCode
self.code += self.callbacks
self.output.insert( INSERT, self.code )
self.output.grid( columnspan = 6 )
# disable buttons to prevent user from using program
self.addButton.config( state = DISABLED )
self.clearButton.config( state = DISABLED )
self.finishButton.config( state = DISABLED )
def clearGUI( self, event ):
"""Clear entire GUI"""
self.addMenuEntry.delete( 0, END )
self.addItemEntry.delete( 0, END )
self.definition.clear()
def generateMenu( self ):
"""Generate the demonstration menu"""
# create window, Frame and MenuBar first time
if self.menuDemo == 0:
top = Tk()
menuWindow = Frame( top )
menuWindow.grid( sticky = N+W+E+S )
self.choices = Pmw.MenuBar( menuWindow )
self.choices.grid()
self.menuDemo += 1
self.expression = self.expression.replace( "\"", "'" )
exp = """"""
for line in self.expression.split( "\n" ):
exp += "\n" + line.strip()
eval( exp )
self.expression = """"""
def main():
CreateMenu().mainloop()
if __name__ == "__main__":
main()
```
![15072|379x312](upload://ktzIR7Mz6BSPzz9gJhI7d8E8xXR.png)