What are the names associated with Python Tkinter get_focus()?

Question:

I have a Tkinter script that has multiple Entry widgets. I have a method that gets the Entry widget that has "focus": i.e. focused = self.root.focus_get() This will return something like this: .!labelframe2.!entry

What I really need to know is

  1. The name of the tk.StringVar() used for the textvariable in the Entry widget
  2. The name of the tk.Entry widget

If you try this code, simply mouse click in any of the Entry widgets and the click the "Who Has Focus" button.

# focus_get.py

import tkinter as tk

class Focus_Get:
    def __init__(self):
        #Create the root window
        self.root = tk.Tk()
        self.root.geometry('300x800')
        self.root.title('Focus_Get')

        #Create a frame
        self.f1 = tk.LabelFrame(self.root,text='This Is The First Frame')
        self.f1.pack(pady=10)
        self.f1e1 = tk.StringVar()
        self.f1e2 = tk.StringVar()

        self.f1e1_label = tk.Label(self.f1,text='Frame 1 Entry 1',).pack(padx=5,pady=5)
        self.f1e1_entry = tk.Entry(self.f1,textvariable=self.f1e1,width='7')
        self.f1e1_entry.pack(pady=5)

        self.f1e2_label = tk.Label(self.f1,text='Frame 1 Entry 2').pack(padx=5,pady=5)
        self.f1e2_entry = tk.Entry(self.f1,textvariable=self.f1e2,width='7')
        self.f1e2_entry.pack(pady=5)

        self.f2 = tk.LabelFrame(self.root,text='This Is The Second Frame')
        self.f2.pack(pady=10)
        self.f2e1 = tk.StringVar()
        self.f2e2 = tk.StringVar()

        self.f2e1_label = tk.Label(self.f2,text='Frame 2 Entry 1').pack(padx=5,pady=5)
        self.f2e1_entry = tk.Entry(self.f2,textvariable=self.f2e1,width='7')
        self.f2e1_entry.pack(pady=5)

        self.f2e2_label = tk.Label(self.f2,text='Frame 2 Entry 2').pack(padx=5,pady=5)
        self.f2e2_entry = tk.Entry(self.f2,textvariable=self.f2e2,width='7')
        self.f2e2_entry.pack(pady=5)

        self.f3 = tk.LabelFrame(self.root,text='This Is The Button Frame')
        self.f3.pack(pady=10)
        self.btn1 = tk.Button(self.f3,text='Who Has Focus',command=self.show_focus).pack(pady=5)
        self.btn2 = tk.Button(self.f3,text='Clear',command=self.clear_focus).pack(pady=5)
        self.btn3 = tk.Button(self.f3,text='Exit',command=self.close_it,).pack(pady=5)

        self.who_text = tk.Listbox(self.root,width=18,height=8,font=('Arial',16))
        self.who_text.pack(pady=5)

        self.root.protocol('WM_DELETE_WINDOW', self.close_it)
        self.root.mainloop()

    def show_focus(self):
        focused = self.root.focus_get()
        self.who_text.insert(tk.END,focused)
        # What I really need to know is
        # 1) The name of the tk.StringVar() used for the textvariable in the Entry widget (i.e. self.f1e1....self.f2e2)
        # 2) The name of the tl.Entry widget (i.e. self.f1e1_entry.....self.f2e2_entry)

    def clear_focus(self):
        self.root.focus()
        self.who_text.delete(0,tk.END)

    def close_it(self):
        self.root.destroy()

if __name__ == '__main__':
    Focus_Get()
Asked By: Pragmatic_Lee

||

Answers:

If the purpose of getting the python variable name is so that you can then get the object itself, just use the focus_get() function:

focused = self.root.focus_get()

Alternatively, if you want the name for other purposes, you can simply store the name in a variable on each object, and then look up the name in your show_focus function. It’s klunky, but it’s quick and dirty and works. Essentially, add the following lines to each Entry object (changing the string to match the variable name, of course):

self.f2e1_entry.stringvar_name = 'f2e1'
self.f2e1_entry.entry_name = 'f2e1_entry'

Then, in your show_focus() function, use focus_get to get the object, and use getattr to get the name:

if hasattr(focused, 'stringvar_name'):
    stringvar_name = getattr(focused, 'stringvar_name')
    self.who_text.insert(tk.END, 'tk.StringVar(): ' + stringvar_name)
if hasattr(focused, 'entry_name'):
    entry_name = getattr(focused, 'entry_name')
    self.who_text.insert(tk.END, 'tl.Entry : ' + entry_name)

Everything put together becomes this:

import tkinter as tk

class Focus_Get:
    def __init__(self):
        #Create the root window
        self.root = tk.Tk()
        self.root.geometry('300x800')
        self.root.title('Focus_Get')

        #Create a frame
        self.f1 = tk.LabelFrame(self.root,text='This Is The First Frame')
        self.f1.pack(pady=10)
        self.f1e1 = tk.StringVar()
        self.f1e2 = tk.StringVar()

        self.f1e1_label = tk.Label(self.f1,text='Frame 1 Entry 1',).pack(padx=5,pady=5)
        self.f1e1_entry = tk.Entry(self.f1,textvariable=self.f1e1,width='7')
        self.f1e1_entry.stringvar_name = 'f1e1'
        self.f1e1_entry.entry_name = 'f1e1_entry'
        self.f1e1_entry.pack(pady=5)

        self.f1e2_label = tk.Label(self.f1,text='Frame 1 Entry 2').pack(padx=5,pady=5)
        self.f1e2_entry = tk.Entry(self.f1,textvariable=self.f1e2,width='7')
        self.f1e2_entry.stringvar_name = 'f1e2'
        self.f1e2_entry.entry_name = 'f1e2_entry'
        self.f1e2_entry.pack(pady=5)

        self.f2 = tk.LabelFrame(self.root,text='This Is The Second Frame')
        self.f2.pack(pady=10)
        self.f2e1 = tk.StringVar()
        self.f2e2 = tk.StringVar()

        self.f2e1_label = tk.Label(self.f2,text='Frame 2 Entry 1').pack(padx=5,pady=5)
        self.f2e1_entry = tk.Entry(self.f2,textvariable=self.f2e1,width='7')
        self.f2e1_entry.stringvar_name = 'f2e1'
        self.f2e1_entry.entry_name = 'f2e1_entry'
        self.f2e1_entry.pack(pady=5)

        self.f2e2_label = tk.Label(self.f2,text='Frame 2 Entry 2').pack(padx=5,pady=5)
        self.f2e2_entry = tk.Entry(self.f2,textvariable=self.f2e2,width='7')
        self.f2e2_entry.stringvar_name = 'f2e2'
        self.f2e2_entry.entry_name = 'f2e2_entry'
        self.f2e2_entry.pack(pady=5)

        self.f3 = tk.LabelFrame(self.root,text='This Is The Button Frame')
        self.f3.pack(pady=10)
        self.btn1 = tk.Button(self.f3,text='Who Has Focus',command=self.show_focus).pack(pady=5)
        self.btn2 = tk.Button(self.f3,text='Clear',command=self.clear_focus).pack(pady=5)
        self.btn3 = tk.Button(self.f3,text='Exit',command=self.close_it,).pack(pady=5)

        self.who_text = tk.Listbox(self.root,width=18,height=8,font=('Arial',16))
        self.who_text.pack(pady=5)

        self.root.protocol('WM_DELETE_WINDOW', self.close_it)
        self.root.mainloop()

    def show_focus(self):
        focused = self.root.focus_get()
        if hasattr(focused, 'stringvar_name'):
            stringvar_name = getattr(focused, 'stringvar_name')
            self.who_text.insert(tk.END, 'tk.StringVar(): ' + stringvar_name)
        if hasattr(focused, 'entry_name'):
            entry_name = getattr(focused, 'entry_name')
            self.who_text.insert(tk.END, 'tl.Entry : ' + entry_name)

    def clear_focus(self):
        self.root.focus()
        self.who_text.delete(0,tk.END)

    def close_it(self):
        self.root.destroy()

if __name__ == '__main__':
    Focus_Get()
Answered By: dbc
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.