Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

problem with OptionMenu.setitems()

Help
2009-05-25
2013-02-21
  • I'm getting an exception when I call Pmw.OptionMenu.setitems(). I originally developed an application using Python 2.5 under win32. Now that I'm trying to upgrade to Python 2.6.2 I've run into this problem - it also occurs with Python 2.5.4.

    I hacked up the OptionMenu.py demo to demonstrate the problem (see below).
    When you click on the first OptionMenu it is supposed to change the items in the second OptionMenu. Has anyone else seen this? Is there a fix?

    Thanks
    Raj

    C:\temp>c:\Python26\python.exe OptionMenuProblem.py
    change type to mineral
    <class '_tkinter.TclError'> Exception in Tk callback
      Function: <function <lambda> at 0x0300B630> (type: <type 'function'>)
      Args: ()
    Traceback (innermost last):
      File "c:\Python26\lib\site-packages\Pmw\Pmw_1_3\lib\PmwBase.py", line 1747, in __call__
        return apply(self.func, args)
      File "c:\Python26\lib\site-packages\Pmw\Pmw_1_3\lib\PmwOptionMenu.py", line 73, in <lambda>
        command = lambda self = self, item = item: self._invoke(item))
      File "c:\Python26\lib\site-packages\Pmw\Pmw_1_3\lib\PmwOptionMenu.py", line 146, in _invoke
        return command(text)
      File "OptionMenuProblem.py", line 47, in _changeType
        self.thing_menu.setitems(self.types[type], 0)
      File "c:\Python26\lib\site-packages\Pmw\Pmw_1_3\lib\PmwOptionMenu.py", line 67, in setitems
        self._menu.delete(0, 'end')
      File "c:\Python26\lib\lib-tk\Tkinter.py", line 2675, in delete
        self.deletecommand(c)
      File "c:\Python26\lib\lib-tk\Tkinter.py", line 358, in deletecommand
        self.tk.deletecommand(name)
    <class '_tkinter.TclError'>: can't delete Tcl command

    C:\temp>c:\Python26\python.exe
    Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> ^Z

    --------- cut here ----------------
    title = 'Pmw.OptionMenu.setitems() problem'

    # Import Pmw from this directory tree.
    import sys
    sys.path[:0] = ['../../..']

    import Tkinter
    import Pmw

    class Demo:
        def __init__(self, parent):
            # Create and pack the OptionMenu megawidgets.
            # The first one has a textvariable.

            self.types = {
                'animal' : [ 'dog', 'cat', 'cow', 'horse', 'sheep' ],
                'vegetable' : [ 'cabbage', 'carrots', 'peas', 'beans', 'rice' ],
                'mineral' : [ 'copper', 'gold', 'coal', 'tin', 'iron' ]
            }

            self.var = Tkinter.StringVar()
            self.var.set('animal')
            self.type_menu = Pmw.OptionMenu(parent,
                    labelpos = 'w',
                    label_text = 'Choose type:',
                    menubutton_textvariable = self.var,
                    items = self.types.keys(),
                    menubutton_width = 10,
                    command = self._changeType,
            )
            self.type_menu.pack(anchor = 'w', padx = 10, pady = 10)

            self.thing_menu = Pmw.OptionMenu (parent,
                    labelpos = 'w',
                    label_text = 'Choose thing:',
                    items = self.types['animal'],
                    menubutton_width = 10,
            )
            self.thing_menu.pack(anchor = 'w', padx = 10, pady = 10)

            menus = (self.type_menu, self.thing_menu)
            Pmw.alignlabels(menus)

        def _changeType(self, type):
            print('change type to ' + type)
            self.thing_menu.setitems(self.types[type], 0)

    ######################################################################

    # Create demo in root window for testing.
    if __name__ == '__main__':
        root = Tkinter.Tk()
        Pmw.initialise(root)
        root.title(title)

        exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy)
        exitButton.pack(side = 'bottom')
        widget = Demo(root)
        root.mainloop()