0

I'm currently creating an adventure game and I want to bind alt+a to my callback. It doesn't do what I want, so I have two questions:

  • Is it possible to bind a function to a Label, too?
  • Why does this (simplyfied) code doesn't work?

Here is the code:

import tkinter as tk

dw = tk.Tk()
dw.title('Hearts')

def play(event):
    print('This is the test.')

areal = tk.Frame(master=dw, width=1200, height=600, bg='blue')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw))
areal.bind("<Alt-A>", play)

dw.mainloop()

It doesn't give me an error, but it doesn't do anything when I click the Frame and afterwards press alt+a. What is wrong here?

EDIT:

import tkinter as tk

def go_fwd(event):
    areal.focus_set()
    print(event.x, event.y)

dw = tk.Tk()
dw.title('Adventure')


areal = tk.Frame(master=dw, width=20000, height=600, bg='blue')
areal.pack_propagate(0)
areal.pack(fill=tk.BOTH, expand=bool(dw)-100)
areal.focus_set()
dw.bind("<Alt-A>", go_fwd)

enter = tk.Frame(master=dw, width=20000, height=100, bg='cyan')
enter.pack(fill=tk.X)

enterentry = tk.Text(master=enter, width=100, height=4, bg='white')
enterentry.pack()
enterbutton = tk.Button(master=enter, text='Senden', bg='red')
enterbutton.pack()

dw.mainloop()

Here is the complete code.

2
  • This is probably a duplicate of stackoverflow.com/q/16923167/7432 Commented Apr 15, 2016 at 16:43
  • I will edit my answer, so you can see my complete code. Commented Apr 15, 2016 at 16:46

2 Answers 2

1

Is it possible to bind a function to a Label, too?

You can bind to any widget you want. However, if you bind key events, the bindings will only work if the widget has focus. By default, most widgets other than Entry and Text don't get focus unless you explicitly set the focus to them.

Note: only one widget can have keyboard focus at a time.

You can also set a binding to the root window, which will cause it to fire no matter what widget has focus.

For a more thorough explanation of how key bindings are processed, see this answer: https://stackoverflow.com/a/11542200/7432

Why does this (simplyfied) code doesn't work?

It doesn't work the way you expect because the binding is on a Frame widget, but that widget doesn't have the keyboard focus. You could give it focus with something like this:

areal.focus_set()

Or, you could only give it focus after you click on the frame, by creating a binding on a mouse click:

areal.bind("<1>", lambda event: areal.focus_set())

Note: you are binding to a capital "A", so make sure when you test that you're pressing control-alt-a

Sign up to request clarification or add additional context in comments.

Comments

1

You need to bind to dw instead of your frame.

So, you can do dw.bind("<Alt-A>", play).

A minor note, Alt-A will bind to the uppercase A as expected, so you'd have to click Alt+Shift+A on your keyboard. Doing Alt+A on your keyboard won't work, you'd have to bind to Alt-a for this to work.

The main window has keyboard focus. Or, alternatively you can leave the bind on the frame and just do areal.focus_set() to set the focus to the frame.

4 Comments

But why does it work fine with left-click and not with alt+a
@ErichSchmidt: key events go to the widget that has focus. Button events go to the widget under the cursor. That's why the binding for a button seems to behave differently than the binding for a key.
@BryanOakley: How do I execute my callback with a key?
@ErichSchmidt: follow the instructions in this answer. Either give focus to the widget with the binding, or put the binding on a widget with focus. By default, clicking on a frame does not give it focus, so a third solution is to add another binding to the frame that sets the focus when it is clicked on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.