从Entry小部件中删除焦点

use*_*650 1 python tkinter

我有一个简单的例子,Entry和三个独立的框架.

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()
Run Code Online (Sandbox Code Playgroud)

一旦我开始在Entry中写入,键盘光标就会停留在那里,即使我用鼠标按下蓝色,绿色或黄色框架.当鼠标按下另一个小部件时,如何停止在Entry中写入?在这个例子中只有三个小部件,除了Entry.但是假设有很多小部件.

Bri*_*ius 6

默认情况下,Frames不要使用键盘焦点.但是,如果要在单击时为其提供键盘焦点,可以通过将focus_set方法绑定到鼠标单击事件来实现:

选项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()
Run Code Online (Sandbox Code Playgroud)

请注意,要做到这一点,你需要保持引用您的小部件,因为我与变量上面那样b,gy.


选项2

这是另一个解决方案,通过创建一个Frame能够获得键盘焦点的子类来实现:

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()
Run Code Online (Sandbox Code Playgroud)

选项3

第三种选择是仅用于bind_all使每个小部件在单击时获得键盘焦点(或者bind_class如果您只想要某些类型的小部件来执行此操作,则可以使用).

只需添加以下行:

top.bind_all("<1>", lambda event:event.widget.focus_set())
Run Code Online (Sandbox Code Playgroud)

  • 添加了第三种解决方案,如果OP希望框架以外的小部件表现出这种行为,他们可能会更喜欢该解决方案。 (2认同)