wxPython 中的 EVT_KILL_FOCUS 事件未触发或处理程序错误

问题描述

下面是一个演示程序(有点长,但很难使 wxPython 应用程序简短)展示了我的困难。该程序要求在 2 个文本字段中输入。每个文本字段都有 2 个处理程序,它们应该捕获事件 EVT_TEXT (hander on_text_changed()) 和 EVT_KILL_FOCUS (handler on_focus_lost())。

当我在任一字段中输入时,处理程序 on_text_changed() 会被调用并打印预期的消息。我希望当我在两个字段之间切换时,或者用鼠标单击一个字段时,应该为失去焦点的字段调用处理程序 on_focus_lost()。但它不会被调用。因此,要么我对事件的用途了解不足,要么我设置事件处理程序的方式有误。

在这里遗漏了什么?

import wx

class DemoFrame(wx.Frame):
    def __init__(self,*args,**kwds):
        kwds["style"] = kwds.get("style",0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self,**kwds)
        self.SetSize((400,300))
        self.SetTitle("Demo")

        self.panel_1 = wx.Panel(self,wx.ID_ANY)

        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)

        self.text_ctrl_1 = wx.TextCtrl(self.panel_1,wx.ID_ANY,"")
        sizer_1.Add(self.text_ctrl_1,0)

        self.text_ctrl_2 = wx.TextCtrl(self.panel_1,"")
        sizer_1.Add(self.text_ctrl_2,0)

        self.panel_1.SetSizer(sizer_1)

        self.Layout()

        self.Bind(wx.EVT_KILL_FOCUS,self.on_focus_lost,self.text_ctrl_1)
        self.Bind(wx.EVT_TEXT,self.on_text_changed,self.text_ctrl_1)
        self.Bind(wx.EVT_KILL_FOCUS,self.text_ctrl_2)
        self.Bind(wx.EVT_TEXT,self.text_ctrl_2)

    def on_focus_lost(self,event):
        print("Event handler for EVT_KILL_FOCUS")
        event.Skip()

    def on_text_changed(self,event):
        print("Event handler for EVT_TEXT,value is",event.String)
        event.Skip()

class DemoApp(wx.App):
    def OnInit(self):
        self.frame = DemoFrame(None,"")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True


if __name__ == "__main__":
    demo = DemoApp(0)
    demo.MainLoop()

解决方法

尝试直接在控件上设置绑定:

 self.text_ctrl_1.Bind(wx.EVT_KILL_FOCUS,self.on_focus_lost)