Remove focus from Entry widget

只谈情不闲聊 提交于 2021-01-24 08:49:35

问题


I have simple example, Entry and three separate Frames.

from tkinter import *

top = Tk()

Entry(top, width="20").pack()
Frame(top, width=200, height=200, bg='blue').pack()
Frame(top, width=200, height=200, bg='green').pack()
Frame(top, width=200, height=200, bg='yellow').pack() 
# Some extra widgets   
Label(top, width=20, text='Label text').pack()
Button(top, width=20, text='Button text').pack()

top.mainloop()

Once I start writing in Entry, the keyboard cursor stay there, even when I press with mouse on blue, green or yellow Frame. How to stop writing in Entry, when mouse presses another widget? In this example only three widgets except Entry. But assume there is alot of widgets.


回答1:


By default, Frames do not take keyboard focus. However, if you want to give them keyboard focus when clicked on, you can do so by binding the focus_set method to a mouse click event:

Option 1

from tkinter import *

top = Tk()

Entry(top, width="20").pack()
b = Frame(top, width=200, height=200, bg='blue')
g = Frame(top, width=200, height=200, bg='green')
y = Frame(top, width=200, height=200, bg='yellow')

b.pack()
g.pack()
y.pack()

b.bind("<1>", lambda event: b.focus_set())
g.bind("<1>", lambda event: g.focus_set())
y.bind("<1>", lambda event: y.focus_set())

top.mainloop()

Note that to do this you'll need to keep references to your widgets, as I did above with the variables b, g, and y.


Option 2

Here is another solution, accomplished by creating a subclass of Frame that is able to take keyboard focus:

from tkinter import *

class FocusFrame(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        self.bind("<1>", lambda event: self.focus_set())

top = Tk()

Entry(top, width="20").pack()
FocusFrame(top, width=200, height=200, bg='blue').pack()
FocusFrame(top, width=200, height=200, bg='green').pack()
FocusFrame(top, width=200, height=200, bg='yellow').pack()    

top.mainloop()

Option 3

A third option is to just use bind_all to make every single widget take the keyboard focus when clicked (or you can use bind_class if you only want certain types of widgets to do this).

Just add this line:

top.bind_all("<1>", lambda event:event.widget.focus_set())


来源:https://stackoverflow.com/questions/24072567/remove-focus-from-entry-widget

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!