wxPython(Phoenix)中的全局事件处理程序

wxPython(Phoenix)中的全局事件处理程序,python,python-3.x,wxpython,Python,Python 3.x,Wxpython,我在处理wxPython 3《凤凰之叉》中的焦点事件时遇到了问题 我试图在TextCtrl处于焦点时清除它的值,如果它仍然有默认值,然后在用户没有输入其他值时在离开焦点时恢复默认值 这是我的处理程序: def on_enter(self, event): control = wx.Window.FindFocus() if control.Id in TEXT_MAPPING.keys(): if control.Value == TEXT_MAPPING[con

我在处理wxPython 3《凤凰之叉》中的焦点事件时遇到了问题

我试图在TextCtrl处于焦点时清除它的值,如果它仍然有默认值,然后在用户没有输入其他值时在离开焦点时恢复默认值

这是我的处理程序:

def on_enter(self, event):
    control = wx.Window.FindFocus()
    if control.Id in TEXT_MAPPING.keys():
        if control.Value == TEXT_MAPPING[control.Id]:
            control.SetValue('')
    exit_control = event.GetWindow()
    if exit_control.Id in (TEXT_MAPPING.keys()):
        if not exit_control.GetValue():
            exit_control.SetValue(TEXT_MAPPING[exit_control.Id])
    event.Skip()
处理器本身工作正常,但有点笨重。我的问题是,我想在全局级别上绑定它,这样每当触发任何
wx.EVT\u SET\u FOCUS
事件时,我都可以让这个函数处理它

我发现:

导入wx

class MyApp(wx.App):
     def FilterEvent(self, evt):
         print evt
         return -1

app = MyApp(redirect=False)
app.SetCallFilterEvent(True)
frm = wx.Frame(None, title='Hello')
frm.Show()
app.MainLoop()

但是我不知道如何将事件传递给
MyApp

的孩子们,您可以做的是将focus kill和focus select绑定到函数,如下所示:

self.user_text.Bind(wx.EVT_SET_FOCUS, self.on_focus_username)
self.user_text.Bind(wx.EVT_KILL_FOCUS, self.on_deselect_username)
def on_focus_username(self, event):
    if self.user_text.GetForegroundColour() != wx.BLACK:
        self.user_text.SetForegroundColour(wx.BLACK)
        # Clear text when clicked/focused
        self.user_text.Clear()

def on_deselect_username(self, event):
    if self.user_text.GetLineLength(0) is 0:
        self.user_text.SetForegroundColour(wx.Colour(192, 192, 192))
        # Put a default message when unclicked/focused away
        self.user_text.SetValue("Enter Username")
其中self是TextCtrl“user\u text”所在的面板

函数可能如下所示:

self.user_text.Bind(wx.EVT_SET_FOCUS, self.on_focus_username)
self.user_text.Bind(wx.EVT_KILL_FOCUS, self.on_deselect_username)
def on_focus_username(self, event):
    if self.user_text.GetForegroundColour() != wx.BLACK:
        self.user_text.SetForegroundColour(wx.BLACK)
        # Clear text when clicked/focused
        self.user_text.Clear()

def on_deselect_username(self, event):
    if self.user_text.GetLineLength(0) is 0:
        self.user_text.SetForegroundColour(wx.Colour(192, 192, 192))
        # Put a default message when unclicked/focused away
        self.user_text.SetValue("Enter Username")

希望这能有所帮助,如果我没有清楚/正确地回答某些问题,请告诉我。

我错过了您在
self
上引用实际组件的部分。它现在可以工作了。我现在的问题是,我希望以多态的方式来完成此操作。我不想为每个TextCtrl编写单独的处理程序。嗯,我从来没有在只有您的地方完成过此操作有一个处理程序。你可以尝试的是,尽管我不确定它是否有效,创建一个
on_focus
on_deselect
单个函数,用于检查由其他函数关闭或打开的布尔数组…编辑:布尔将指示哪些东西刚刚离开或聚焦。我不能像
self这样做。GetComponentByID(event.GetWindow().Id)
?但是,在您最初的问题中,您确实说了“文本Ctrl”。即使您有<10个文本Ctrl,这仍然是最干净的方法之一,因为您可以自定义背景、效果等。