searchctrl EVT_LEFT_DOWN 事件不工作(wxpython)

searchctrl EVT_LEFT_DOWN event is not working (wxpython)

当我点击 searchctrl 以输入一些代码时,我试图用 searchctrl 创建一个鼠标事件。 我的目标是,当我单击 searchctrl(编辑为文本或 wirte)时,虚拟键盘(板载)将启动。我发现 searchctrl 是低类别的 textctrl。但是 wx.EVT_LEFT_DOWN 不工作 我怎样才能使它起作用(我认为这是可能的。因为当我单击 searchctrl(text)

时 value=””(hint) 消失了

完整代码

# -*- coding: utf-8 -*-

import wx

[wxID_FRAME1, wxID_FRAME1TEXTCTRL1,
] = [wx.NewId() for _init_ctrls in range(2)]

class MyFrame1 ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY,
            title = wx.EmptyString, pos = wx.DefaultPosition,
            size = wx.Size( 700,400 ),
          #  style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL
        )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        # Create controls
        sb = wx.StaticBox(self, -1, "Options")
        searchBtnOpt = wx.CheckBox(self, -1, "Search button")
        searchBtnOpt.SetValue(True)
        cancelBtnOpt = wx.CheckBox(self, -1, "Cancel button")
        menuBtnOpt   = wx.CheckBox(self, -1, "Search menu")

        self.search = wx.SearchCtrl(self,size=(200,-1), style=wx.TE_PROCESS_ENTER)
        #self.search.SetHint(self, love)
        # Setup the layout
        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick, self.search)
        box = wx.StaticBoxSizer(sb, wx.VERTICAL)
        box.Add(searchBtnOpt, 0, wx.ALL, 5)
        box.Add(cancelBtnOpt, 0, wx.ALL, 5)
        box.Add(menuBtnOpt,   0, wx.ALL, 5)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(box, 0, wx.ALL, 15)
        sizer.Add((15,15))
        sizer.Add(self.search, 0, wx.ALL, 15)

##         self.tc = wx.TextCtrl(self)  # just for testing that heights match...
##         sizer.Add(self.tc, 0, wx.TOP, 15)

        self.SetSizer(sizer)

        self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1',
              parent=self, pos=wx.Point(120, 80), size=wx.Size(100, 21),
              style=0, value='textCtrl1')
        self.textCtrl1.Bind(wx.EVT_LEFT_DOWN, self.OnClick)


        # Set event bindings
        self.Bind(wx.EVT_CHECKBOX, self.OnToggleSearchButton, searchBtnOpt)
        self.Bind(wx.EVT_CHECKBOX, self.OnToggleCancelButton, cancelBtnOpt)
        self.Bind(wx.EVT_CHECKBOX, self.OnToggleSearchMenu,   menuBtnOpt)
        self.search.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
        self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.OnSearch, self.search)
        self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.OnCancel, self.search)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.search)
        ##self.Bind(wx.EVT_TEXT, self.OnDoSearch, self.search)


    def OnToggleSearchButton(self, evt):
        self.search.ShowSearchButton( evt.GetInt() )

    def OnToggleCancelButton(self, evt):
        self.search.ShowCancelButton( evt.GetInt() )

    def OnToggleSearchMenu(self, evt):
        if evt.GetInt():
            self.search.SetMenu( self.MakeMenu() )
        else:
            self.search.SetMenu(None)

    def OnClick(self, event):
        print "333"

    def OnSearch(self, evt):
        print "555"

    def OnCancel(self, evt):
        self.log.write("OnCancel")

    def OnDoSearch(self, evt):
        self.log.write("OnDoSearch: " + self.search.GetValue())
        print "555"


    def MakeMenu(self):
        menu = wx.Menu()
        item = menu.Append(-1, "Recent Searches")
        item.Enable(False)
        for txt in [ "You can maintain",
                     "a list of old",
                     "search strings here",
                     "and bind EVT_MENU to",
                     "catch their selections" ]:
            menu.Append(-1, txt)
        return menu
    def __del__( self ):
        pass


    # Virtual event handlers, overide them in your derived class
    def searchCtrlOnSearchButton( self, event ):
        print("SearchCtrl SEARCH_BTN clicked")
        event.Skip()

    def searchCtrlOnTextEnter( self, event ):
        print("SearchCtrl ENTER pressed")
        event.Skip()


if __name__ == '__main__':
    app = wx.PySimpleApp( 0 )
    frame = MyFrame1( None )
    frame.Show()
    app.MainLoop()

这部分是问题所在

    self.search = wx.SearchCtrl(self,size=(200,-1), style=wx.TE_PROCESS_ENTER)
    self.Bind(wx.EVT_LEFT_DOWN, self.OnClick, self.search)

    self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1',
          parent=self, pos=wx.Point(120, 80), size=wx.Size(100, 21),
          style=0, value='textCtrl1')
    self.textCtrl1.Bind(wx.EVT_LEFT_DOWN, self.OnClick)

    self.search.Bind(wx.EVT_LEFT_DOWN, self.OnClick)

def OnClick(self, event):
    print "333"

从更高层次的角度来看,在搜索控件上捕获鼠标事件可能不是一个好主意,但最好绑定到文档中列出的内容(文本输入、按回车、按 search/clear 按钮,...).

这就是说,我使用 wxPython WIT(小部件检查工具)来可视化正在发生的事情。通过在主循环之前添加以下内容来激活它:

    ...
    import wx.lib.inspection
    wx.lib.inspection.InspectionTool().Show()

    app.MainLoop()

如果您浏览左侧窗格中的小部件树,您可以看到 SearchCtrl 有一个 TextCtrl 作为它的子项,名为 text。如果您进一步单击小部件树中的 TextCtrl 并激活工具栏中的事件 window,您会看到它正在获取所有 wx.EVT_LEFT_DOWN 事件。我不知道为什么搜索控件不继承文本控件的鼠标事件。它收到EVT_TEXT!您可以这样做:

    self.search = wx.SearchCtrl(#...

    search_txtctrl = self.search.FindWindowByName('text')
    search_txtctrl.Bind(wx.EVT_LEFT_DOWN, self.OnClick)

def OnClick(self, evt)
    # do your stuff
    evt.Skip()

此时不要忘记跳过,否则搜索控件中的wx.TextCtrl将收不到任何鼠标按下事件!