import types
import Tkinter
import Pmw
class OptionMenu(Pmw.MegaWidget):
def __init__(self, parent = None, **kw):
# Define the megawidget options.
INITOPT = Pmw.INITOPT
optiondefs = (
('command', None, None),
('items', (), INITOPT),
('initialitem', None, INITOPT),
('labelmargin', 0, INITOPT),
('labelpos', None, INITOPT),
)
self.defineoptions(kw, optiondefs)
# Initialise the base class (after defining the options).
Pmw.MegaWidget.__init__(self, parent)
# Create the components.
interior = self.interior()
self._menubutton = self.createcomponent('menubutton',
(), None,
Tkinter.Menubutton, (interior,),
borderwidth = 2,
indicatoron = 1,
relief = 'raised',
anchor = 'c',
highlightthickness = 2,
direction = 'flush',
)
self._menubutton.grid(column = 2, row = 2, sticky = 'nsew')
self._menu = self.createcomponent('menu',
(), None,
Tkinter.Menu, (self._menubutton,),
tearoff=0
)
self._menubutton.configure(menu = self._menu)
interior.grid_columnconfigure(2, weight = 1)
interior.grid_rowconfigure(2, weight = 1)
# Create the label.
self.createlabel(interior)
# Add the items specified by the initialisation option.
self.setitems(self['items'], self['initialitem'])
# Check keywords and initialise options.
self.initialiseoptions(OptionMenu)
def setitems(self, items, index = None):
# Set the items in the menu component.
self._menu.delete(0, 'end')
self._itemList = tuple(items)
for item in items:
self._menu.add_command(label = item,
command = lambda self = self, item = item: self.invoke(item))
# Set the currently selected value.
var = self._menubutton.cget('textvariable')
if index is None:
if var != '':
# None means do not change text variable.
return
if len(items) == 0:
text = ''
else:
text = items[0]
else:
index = self.index(index)
text = self._itemList[index]
if var == '':
self._menubutton.configure(text = text)
else:
self._menu.tk.globalsetvar(var, text)
def get(self):
var = self._menubutton.cget('textvariable')
if var == '':
return self._menubutton.cget('text')
else:
return self._menu.tk.globalgetvar(var)
def index(self, index):
# Return the integer index of the item with the given index.
listLength = len(self._itemList)
if type(index) == types.IntType:
if index < listLength:
return index
else:
raise ValueError, 'index "%s" is out of range' % index
elif index == 'end':
if listLength > 0:
return listLength - 1
else:
raise ValueError, 'OptionMenu has no items'
else:
if index is None:
if listLength > 0:
index = self.get()
else:
raise ValueError, 'OptionMenu has no items'
for count in range(listLength):
name = self._itemList[count]
if index == name:
return count
validValues = 'number, end, a name or None'
raise ValueError, \
'bad index "%s": must be %s' % (index, validValues)
def invoke(self, index = None):
index = self.index(index)
text = self._itemList[index]
var = self._menubutton.cget('textvariable')
if var == '':
self._menubutton.configure(text = text)
else:
self._menu.tk.globalsetvar(var, text)
command = self['command']
if callable(command):
return command(text)