从Entry控件移除焦点

3 投票
1 回答
4376 浏览
提问于 2025-04-18 08:48

我有一个简单的例子,里面有一个输入框(Entry)和三个不同的框(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()

当我在输入框里开始输入时,光标会一直停留在输入框里,即使我用鼠标点击蓝色、绿色或黄色的框。怎么才能在点击其他控件时,让输入框停止输入呢?在这个例子里只有三个控件,除了输入框之外。但假设有很多控件的话,情况也是一样的。

1 个回答

10

默认情况下,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()

需要注意的是,为了做到这一点,你需要保留对你的控件的引用,就像我在上面用变量 bgy 所做的那样。


选项 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()

选项 3

第三种选择是使用 bind_all,让每一个控件在被点击时都能获得键盘焦点(如果你只想让某些类型的控件这样做,可以使用 bind_class)。

只需添加这一行:

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

撰写回答