[Tkinter-discuss] Bind to event related to currently selected menu item

python at bdurham.com python at bdurham.com
Sun Nov 21 19:00:51 CET 2010


Hi Michael,

> The problem is apparently that the widget name of the menu's "button" is assigned by Tk and there does not seem to be a way to access this subwidget from within Tkinter. Besides this I don't understand why this does not happen with the context
menu from my previous example but only with a cascaded menu.

Your example fails for both context and cascading menus under 32-bit
Python 2.7 for Windows.

I appreciate your and Michael's help. Thank you both!

Malcolm

<snipped>
Thus spoketh "Michael O'Donnell" <michael.odonnell at uam.es> 
unto us on Sun, 21 Nov 2010 10:26:24 +0100:

> Hi Malcom,
> 
> Change your statusbarUpdate for the following, which will print out
> the index of the currently selected menu item:
> 
> def statusbarUpdate( event=None ):
>    print tk.call(event.widget, "index", "active")
> 
> Note that this uses tcl/tk code, where Tkinter code should be used,
> but it seems the corresponding tkinter code is broken, e.g., with
> 
> def statusbarUpdate( event=None ):
>    print popup.index('active')
> 
> ...always returns None on changing the menu selection.

I believe this is because the button in the menu is treated as a
different
widget by Tk, so the correct call would be:

    def statusbarUpdate(event):
        print event.widget.index('active')

However, using this I get an error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/lib-tk/Tkinter.py", line 1410, in
__call__ return self.func(*args)
  File "test2.py", line 18, in statusbarUpdate
    print event.widget.index('active')
ValueError: substring not found

This is apparently because event.widget is not (as expected) a widget
instance but a string which looks like .#153369036.#153369036#153369644

Trying to feed this string to nametowidget() I get the following error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/lib-tk/Tkinter.py", line 1410, in
__call__ return self.func(*args)
  File "test2.py", line 18, in statusbarUpdate
    print tk.nametowidget(event.widget)#.index('active')
  File "/usr/local/lib/python2.6/lib-tk/Tkinter.py", line 1079, in
nametowidget w = w.children[n]
KeyError: '#153369036'

The problem is apparently that the widget name of the menu's "button" is
assigned by Tk and there does not seem to be a way to access this
subwidget from within Tkinter.
Besides this I don't understand why this does not happen with the
context
menu from my previous example but only with a cascaded menu.

This looks to me like a bug in Tkinter, but I don't have an idea how
this
could ever be fixed (at least without dealing with _tkinter's
internals),
so we probably will have to stick with Michael's workaround.
</snipped>


More information about the Tkinter-discuss mailing list