1from Tkinter import *
2
3# some vocabulary to keep from getting confused. This terminology
4# is something I cooked up for this file, but follows the man pages
5# pretty closely
6#
7#
8#
9#       This is a MENUBUTTON
10#       V
11# +-------------+
12# |             |
13#
14# +------------++------------++------------+
15# |            ||            ||            |
16# |  File      ||  Edit      || Options    |   <-------- the MENUBAR
17# |            ||            ||            |
18# +------------++------------++------------+
19# | New...         |
20# | Open...        |
21# | Print          |
22# |                |  <-------- This is a MENU. The lines of text in the menu are
23# |                |                            MENU ENTRIES
24# |                +---------------+
25# | Open Files >   | file1         |
26# |                | file2         |
27# |                | another file  | <------ this cascading part is also a MENU
28# +----------------|               |
29#                  |               |
30#                  |               |
31#                  |               |
32#                  +---------------+
33
34
35
36# some miscellaneous callbacks
37def new_file():
38    print "opening new file"
39
40def open_file():
41    print "opening OLD file"
42
43def print_something():
44    print "picked a menu item"
45
46
47
48anchovies = 0
49
50def print_anchovies():
51    global anchovies
52    anchovies = not anchovies
53    print "anchovies?", anchovies
54
55def makeCommandMenu():
56    # make menu button
57    Command_button = Menubutton(mBar, text='Simple Button Commands',
58                                underline=0)
59    Command_button.pack(side=LEFT, padx="2m")
60
61    # make the pulldown part of the File menu. The parameter passed is the master.
62    # we attach it to the button as a python attribute called "menu" by convention.
63    # hopefully this isn't too confusing...
64    Command_button.menu = Menu(Command_button)
65
66    # just to be cute, let's disable the undo option:
67    Command_button.menu.add_command(label="Undo")
68    # undo is the 0th entry...
69    Command_button.menu.entryconfig(0, state=DISABLED)
70
71    Command_button.menu.add_command(label='New...', underline=0,
72                                    command=new_file)
73    Command_button.menu.add_command(label='Open...', underline=0,
74                                    command=open_file)
75    Command_button.menu.add_command(label='Different Font', underline=0,
76                                    font='-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*',
77                                    command=print_something)
78
79    # we can make bitmaps be menu entries too. File format is X11 bitmap.
80    # if you use XV, save it under X11 bitmap format. duh-uh.,..
81    Command_button.menu.add_command(
82        bitmap="info")
83        #bitmap='@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm')
84
85    # this is just a line
86    Command_button.menu.add('separator')
87
88    # change the color
89    Command_button.menu.add_command(label='Quit', underline=0,
90                                    background='red',
91                                    activebackground='green',
92                                    command=Command_button.quit)
93
94    # set up a pointer from the file menubutton back to the file menu
95    Command_button['menu'] = Command_button.menu
96
97    return Command_button
98
99
100
101def makeCascadeMenu():
102    # make menu button
103    Cascade_button = Menubutton(mBar, text='Cascading Menus', underline=0)
104    Cascade_button.pack(side=LEFT, padx="2m")
105
106    # the primary pulldown
107    Cascade_button.menu = Menu(Cascade_button)
108
109    # this is the menu that cascades from the primary pulldown....
110    Cascade_button.menu.choices = Menu(Cascade_button.menu)
111
112    # ...and this is a menu that cascades from that.
113    Cascade_button.menu.choices.weirdones = Menu(Cascade_button.menu.choices)
114
115    # then you define the menus from the deepest level on up.
116    Cascade_button.menu.choices.weirdones.add_command(label='avacado')
117    Cascade_button.menu.choices.weirdones.add_command(label='belgian endive')
118    Cascade_button.menu.choices.weirdones.add_command(label='beefaroni')
119
120    # definition of the menu one level up...
121    Cascade_button.menu.choices.add_command(label='Chocolate')
122    Cascade_button.menu.choices.add_command(label='Vanilla')
123    Cascade_button.menu.choices.add_command(label='TuttiFruiti')
124    Cascade_button.menu.choices.add_command(label='WopBopaLoopBapABopBamBoom')
125    Cascade_button.menu.choices.add_command(label='Rocky Road')
126    Cascade_button.menu.choices.add_command(label='BubbleGum')
127    Cascade_button.menu.choices.add_cascade(
128        label='Weird Flavors',
129        menu=Cascade_button.menu.choices.weirdones)
130
131    # and finally, the definition for the top level
132    Cascade_button.menu.add_cascade(label='more choices',
133                                    menu=Cascade_button.menu.choices)
134
135    Cascade_button['menu'] = Cascade_button.menu
136
137    return Cascade_button
138
139def makeCheckbuttonMenu():
140    global fred
141    # make menu button
142    Checkbutton_button = Menubutton(mBar, text='Checkbutton Menus',
143                                    underline=0)
144    Checkbutton_button.pack(side=LEFT, padx='2m')
145
146    # the primary pulldown
147    Checkbutton_button.menu = Menu(Checkbutton_button)
148
149    # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options
150    # are not supported correctly at present. You have to do all your application
151    # work through the calback.
152    Checkbutton_button.menu.add_checkbutton(label='Pepperoni')
153    Checkbutton_button.menu.add_checkbutton(label='Sausage')
154    Checkbutton_button.menu.add_checkbutton(label='Extra Cheese')
155
156    # so here's a callback
157    Checkbutton_button.menu.add_checkbutton(label='Anchovy',
158                                            command=print_anchovies)
159
160    # and start with anchovies selected to be on. Do this by
161    # calling invoke on this menu option. To refer to the "anchovy" menu
162    # entry we need to know it's index. To do this, we use the index method
163    # which takes arguments of several forms:
164    #
165    # argument        what it does
166    # -----------------------------------
167    # a number        -- this is useless.
168    # "last"          -- last option in the menu
169    # "none"          -- used with the activate command. see the man page on menus
170    # "active"        -- the currently active menu option. A menu option is made active
171    #                         with the 'activate' method
172    # "@number"       -- where 'number' is an integer and is treated like a y coordinate in pixels
173    # string pattern  -- this is the option used below, and attempts to match "labels" using the
174    #                    rules of Tcl_StringMatch
175    Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy'))
176
177    # set up a pointer from the file menubutton back to the file menu
178    Checkbutton_button['menu'] = Checkbutton_button.menu
179
180    return Checkbutton_button
181
182
183def makeRadiobuttonMenu():
184    # make menu button
185    Radiobutton_button = Menubutton(mBar, text='Radiobutton Menus',
186                                    underline=0)
187    Radiobutton_button.pack(side=LEFT, padx='2m')
188
189    # the primary pulldown
190    Radiobutton_button.menu = Menu(Radiobutton_button)
191
192    # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options
193    # are not supported correctly at present. You have to do all your application
194    # work through the calback.
195    Radiobutton_button.menu.add_radiobutton(label='Republican')
196    Radiobutton_button.menu.add_radiobutton(label='Democrat')
197    Radiobutton_button.menu.add_radiobutton(label='Libertarian')
198    Radiobutton_button.menu.add_radiobutton(label='Commie')
199    Radiobutton_button.menu.add_radiobutton(label='Facist')
200    Radiobutton_button.menu.add_radiobutton(label='Labor Party')
201    Radiobutton_button.menu.add_radiobutton(label='Torie')
202    Radiobutton_button.menu.add_radiobutton(label='Independent')
203    Radiobutton_button.menu.add_radiobutton(label='Anarchist')
204    Radiobutton_button.menu.add_radiobutton(label='No Opinion')
205
206    # set up a pointer from the file menubutton back to the file menu
207    Radiobutton_button['menu'] = Radiobutton_button.menu
208
209    return Radiobutton_button
210
211
212def makeDisabledMenu():
213    Dummy_button = Menubutton(mBar, text='Dead Menu', underline=0)
214    Dummy_button.pack(side=LEFT, padx='2m')
215
216    # this is the standard way of turning off a whole menu
217    Dummy_button["state"] = DISABLED
218    return Dummy_button
219
220
221#################################################
222#### Main starts here ...
223root = Tk()
224
225
226# make a menu bar
227mBar = Frame(root, relief=RAISED, borderwidth=2)
228mBar.pack(fill=X)
229
230Command_button     = makeCommandMenu()
231Cascade_button     = makeCascadeMenu()
232Checkbutton_button = makeCheckbuttonMenu()
233Radiobutton_button = makeRadiobuttonMenu()
234NoMenu             = makeDisabledMenu()
235
236# finally, install the buttons in the menu bar.
237# This allows for scanning from one menubutton to the next.
238mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu)
239
240
241root.title('menu demo')
242root.iconname('menu demo')
243
244root.mainloop()
245