How do you check if a widget has focus in Tkinter?

2020-03-01 08:39发布

问题:

from Tkinter import *

app = Tk()
text_field = Entry(app)
text_field.pack()
app.mainloop()

I want to be able to check if text_field is currently selected or focused, so that I know whether or not to do something with its contents when the user presses enter.

回答1:

If you want to do something when the user presses enter only if the focus is on the entry widget, simply add a binding to the entry widget. It will only fire if that widget has focus. For example:

import tkinter as tk

root = tk.Tk()
e1 = tk.Entry(root)
e2 = tk.Entry(root)
e1.pack()
e2.pack()

def handleReturn(event):
    print("return: event.widget is",event.widget)
    print("focus is:", root.focus_get())

e1.bind("<Return>", handleReturn)

Notice that the handler is only called if the first entry has focus when you press return.

If you really want a global binding and need to know which widget has focus, use the focus_get() method on the root object. In the following example a binding is put on "." (the main toplevel) so that it fires no matter what has focus:

import tkinter as tk

root = tk.Tk()
e1 = tk.Entry(root)
e2 = tk.Entry(root)
e1.pack()
e2.pack()

def handleReturn(event):
    print("return: event.widget is",event.widget)
    print("focus is:",root.focus_get())

root.bind("<Return>", handleReturn)

Notice the difference between the two: in the first example, the handler will only be called when you press return in the first entry widget. There is no need to check which widget has focus. In the second example, the handler will be called no matter which widget has focus.

Both solutions are good depending on what you really need to have happened. If your main goal is to only do something when the user presses return in a specific widget, use the former. If you want a global binding, but in that binding do something different based on what has or doesn't have focus, do the latter example.