Tkinter: neither underline=1 nor bind() work on a Button

Eric Brunel eric.brunel at pragmadev.com
Tue Jan 14 04:16:37 EST 2003


morden wrote:
> Here is modified snippet from Dialog.py:
> 
> if __name__ == '__main__':
>      t = Button(None, {'text': 'Test',
>                        'command': _test,
>                        Pack: {}}, underline=1)
>      t.bind('<Key-Meta_L>, <Key-t>', _test)
>      t.bind('<Key-Alt_L>, <Key-t>', _test)
>      t.bind('<Key-t>', _test)
>      q = Button(None, {'text': 'Quit',
>                        'command': t.quit,
>                        Pack: {}})
>      t.mainloop()
> 
> 
> Alt-t does not work. Neither does Ctrl-t or plain t.
> Pressing the button with the mouse does invoke _test.
> Alt-e does not work.
> 
> Any ideas on how to fix this?

First, I don't know where you found this utterly horrible syntax for 
Tkinter calls. In fact, it's a part of your problem:
- Bindings in Tkinter/Tk only fire when the widget they're on have the 
input focus. Since buttons do not get "naturally" the input focus, they 
won't fire when you just run the program and press the key. Try to run your 
program, press the "tab" key until there's a black frame around your "Test" 
button, and press Alt-t. It should work...
- But: generally, you obviously want the whole window to respond to the key 
events, not only the button. So you shouldn't do the binding on t, but on 
the whole window. And here is the problem with your code: you never 
explicitely create the window, which is a bad idea...

So here is my modified version of your code, with a more usual syntax and 
IMHO much more readable:

-----------------------------------------------------------
from Tkinter import *

def _test(*whatever): print 'Hurray, it works!!!'

root = Tk()

t = Button(root, text='Test', command=_test, underline=1)
t.pack()

root.bind('<Meta-t>', _test)
root.bind('<Alt-t>', _test)
root.bind('<t>', _test)

q = Button(root, text='Quit', command = root.quit)
q.pack()

root.mainloop()
-----------------------------------------------------------

Notice I've done the bindings on root, which is the root window of your 
program. I also used another form for the events firing the binding, which 
is a bit different from what you wrote, but actually does what you expect. 
The "*whatever" parameter for the _test function is here because the 
function will get called differently from the button's command and from the 
bindings: there's a parameter passed to the function when it's a binding, 
and none when it's a button's command. The "*whatever" stuff just gets 
everything and ignores it.

For a more complete introduction, you may want to read:
http://www.pythonware.com/library/tkinter/introduction/index.htm

HTH
-- 
- Eric Brunel <eric.brunel at pragmadev.com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com




More information about the Python-list mailing list