[wxPython] tab-order and focus

In the demo application listed below, when the user presses <Enter>
the OnEnter() method is called, printing a message to the console.
When the user presses <Tab>, focus is passed to the next text
control. When the user presses <Tab> again, focus is passed to the
slider, then to the button, then back to the first text control.
But NOW when the user presses <Enter> the OnEnter() method is NO
LONGER called. This is because the button is now set as the default
button for <Return> for the panel.

Is there a way to remove a given control (especially the button,
and probably the slider) from the tab-order, so that the button
never becomes the "default" for <Return>?

Also, is there a way to force one text control to pass the focus to
the next text control in the tab order? Is there a command that can
be placed in the OnEnter() method?

···

#################################################################
from wxPython.wx import *

class MyTextCtrl(wxTextCtrl):

    def __init__(self, parent):
        wxTextCtrl.__init__(self, parent, -1)
        EVT_TEXT_ENTER(self, self.GetId(), self.OnEnter)

    def OnEnter(self, event):
        print 'enter key pressed'
        # put code here to tab on to next text control
        
class TopWin(wxFrame):
    def __init__(self, parent=None, id=-1, title='Focus Demo'):
        wxFrame.__init__(self, parent, id, title)
        panel = wxPanel(self, -1)
        t1 = MyTextCtrl(panel)
        t2 = MyTextCtrl(panel)
        s1 = wxSlider(panel, -1, 0, 0, 1000)
        b1 = wxButton(panel, 10, 'Press Me')
        EVT_BUTTON(self, 10, self.OnPress)

        box1 = wxBoxSizer(wxVERTICAL)
        box1.Add(t1, 1, wxEXPAND)
        box1.Add(t2, 1, wxEXPAND)
        box1.Add(s1, 1, wxEXPAND)
        box1.Add(b1, 1, wxEXPAND)
        panel.SetSizer(box1)
        panel.Layout()
        panel.SetAutoLayout(true)
        box1.Fit(self)
        box1.SetSizeHints(self)

    def OnPress(self, event):
        print 'Button Pressed'

class App(wxApp):
    def OnInit(self):
        top = TopWin()
        top.Show(true)
        self.SetTopWindow(top)
        return true

if __name__ == '__main__':
    app = App(0)
    app.MainLoop()
#################################################################

=====
Donnal Walter
Arkansas Children's Hospital

__________________________________________________
Do You Yahoo!?
Send FREE video emails in Yahoo! Mail!
http://promo.yahoo.com/videomail/

In the demo application listed below, when the user presses <Enter>
the OnEnter() method is called, printing a message to the console.
When the user presses <Tab>, focus is passed to the next text
control. When the user presses <Tab> again, focus is passed to the
slider, then to the button, then back to the first text control.
But NOW when the user presses <Enter> the OnEnter() method is NO
LONGER called. This is because the button is now set as the default
button for <Return> for the panel.

I don't like this either, but IIRC it was done to conform to some MSW
standard.

Is there a way to remove a given control (especially the button,
and probably the slider) from the tab-order, so that the button
never becomes the "default" for <Return>?

No.

Also, is there a way to force one text control to pass the focus to
the next text control in the tab order?

You can catch the EVT_KILL_FOCUS event for the control and explicitly set
focus to some other control, but that would also be called if you left the
field with the mouse, shift-tab, etc.

You may also be able to do it by catching EVT_NAVIGATION_KEY, but I don't
know as much about that...

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Is there a way to remove a given control (especially the button,
and probably the slider) from the tab-order, so that the button
never becomes the "default" for <Return>?

class myButton(wxButton):
    def __init__(self, *_args, **_kwargs):
        apply(wxButton.__init__, (self,) + _args, _kwargs)
        EVT_CHAR(self, self.OnChar)
    def OnChar(self,evt):
        if not self.IsEnabled():
            return
        key = evt.KeyCode()
        if key in [WXK_DOWN,WXK_UP,WXK_RETURN]:
            MoveFocus(self, key in [WXK_DOWN,WXK_RETURN])
            return
        evt.Skip()

Also, is there a way to force one text control to pass the focus to
the next text control in the tab order? Is there a command that can
be placed in the OnEnter() method?

def MoveFocus(sender,tonext):
        nevt=wxNavigationKeyEvent()
        nevt.SetDirection(tonext)
        nevt.SetWindowChange(0)
        nevt.SetEventObject(sender)
        sender.GetParent().GetEventHandler().ProcessEvent(nevt)
        del nevt

This code works for me, but sometimes I need also invoke
dialog.SetDefaultItem(None)

mak