焦点事件在焦点未聚焦时仍然触发

0 投票
1 回答
1374 浏览
提问于 2025-04-18 04:00

我正在创建一个gtk.Entry(就是一个输入框),想要在它获得焦点的时候,弹出一个虚拟键盘:

class LabelEntry(gtk.HBox):
    # ... initialization ...

    self.keyboard = virtualkeyboard.VirtualKeyboard()
    self.entry = gtk.Entry()
    self.entry.connect('focus-in-event', self.keyboard.focus_handler)

    # ... attach the gtk.Entry to this gtk.HBox, etc. ...

这样做可以正确调用VirtualKeyboard类里的focus_handler回调函数,然后在当前窗口上方显示一个新窗口。

当我关闭虚拟键盘窗口后,我能看到原来的窗口,并且self.entry的值已经更新了。但是,如果我在原窗口的任何地方点击(甚至不是在gtk.Entry上),同样的回调函数又会被触发,虚拟键盘又会显示出来。

是什么原因导致在原窗口的任何点击都被当作gtk.Entry的“获得焦点”事件呢?我是否需要在打开新窗口时让焦点失去,或者设置一个标志,表明我已经打开过窗口,不应该再打开它?

编辑

这个问题来自于一个修改过的版本,是wicd 1.7guiutil.py文件,加上一个新的虚拟键盘(python文件glade文件),这个虚拟键盘应该在选择输入框时打开。

我想避免复杂的逻辑,比如“这个地方之前被点击过吗?你刚刚失去焦点了吗?你刚刚又获得焦点了,但之前被点击过,需要忽略这次焦点事件吗?”这样的难题。

1 个回答

0

键盘焦点进入这个小部件的窗口时,会发出一个叫做::focus-in-event的信号。

要接收到这个信号,和这个小部件相关的GdkWindow需要开启GDK_FOCUS_CHANGE_MASK这个设置。

所以这是我们想要的行为。

要实现这个功能,你可以检查一下你想要的小部件是否真的获得了焦点,可以用gtk_widget_is_focus(...)这个方法(注意,这和gtk_widget_has_focus(...)是不同的,具体区别可以查阅相关资料)。

撰写回答