Skip to content
Advertisement

tkinter: Disable the focus on each widget

With tkinter you can deactivate the focus of a single widget

tk.Button(root, takefocus=False)

Is it also possible to disable this for all widgets at once?

Edit: By “all” I mean all tk and ttk widgets present in the window.

Advertisement

Answer

takefocus is a standard option in tkinter and ttk. So all you have to do is to recursively loop over the widgets and configure them as desired. The function should look like this:

def disable_takefocus(widget):
    for w in widget.winfo_children():
        w.configure(takefocus=False)
        disable_takefocus(w) 
disable_takefocus(root)

Be aware this should be called AFTER you created ALL FINAL widgets. If you dynamically add and delete widgets to your window, it won’t help. A general solution for ttk and tkinter does not seem to be possible due the different style engines. For tkinter widgets you could use option_add, but for ttk it is a different animal. Ttk uses a style engine with a fallback chain. It is not easy to spot where the option will be garbed from especially if you take the different themes into account.

For ttk it seems to be the easiest to define styles for each widget.

Of course you could bind ‘<Configure>’ to all widgets or just containers and call this or a similar function to force that option to be False. But this way you produce a overhead in your event queue. This does not look like a good trade of that can be avoided with a few lines of code.


There is another technique you might not know about and can help to have default options. The options are parsed as keyword arguments therefor you could define a dictionary with default values and unpack them in the constructor interface. As an example:

defaults = {
    'takefocus' : False,
    'background' : '#000000',
    'foreground' : '#ffffff',
    }
label = tk.Label(root, **defaults)
label.pack()
button = ttk.Button(root, **defaults)
button.pack()
Advertisement