Question

I think this must be a pretty basic question, but I have Googled it to death with no clear answer, so here goes: I have a TextCtrl and I want a pretty basic sequence of events: 1) The user moves focus to the control by hook or by crook. 2) The user types something in the TextCtrl. 3) The user hits return or tab. 4) At this point, the code grabs the text in the TextCtrl, does some simple processing, and then moves focus to whatever control is next in the tabbing order.

Can anyone tell me how to do this? It seems so basic to me, but I can't find the answer anywhere. Sorry if I've missed something obvious.

Was it helpful?

Solution

To get this to work properly, you will need to catch key events and check to see if the user has pressed the Enter or Tab keys. As @sundar as already mentioned, to get tabbing to work correctly on all platforms, the widgets need to be children of a panel. Here's a fairly simple example:

import wx

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        self.text = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
        self.text.Bind(wx.EVT_KEY_DOWN, self.onEnter)
        btn = wx.Button(self, label="Do something")
        self.text.SetFocus()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.text, 0, wx.EXPAND|wx.ALL, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(sizer)

    #----------------------------------------------------------------------
    def onEnter(self, event):
        """"""
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER or keycode == wx.WXK_TAB:
            self.process_text(event=None)
            event.EventObject.Navigate()
        event.Skip()

    #----------------------------------------------------------------------
    def process_text(self, event):
        """
        Do something with the text
        """
        text = self.text.GetValue()
        print text.upper()
        for word in text.split():
            print word

########################################################################
class MyFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="TextCtrl Demo")
        panel = MyPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

Here we bind to wx.EVT_KEY_DOWN and have it extract the keycode that was pressed. Then it checks to see if the keycode is the Enter or Tab key. If it is, it calls a function to process the text and then it calls event.EventObject.Navigate(), which will cause wxPython to move the focus to the next widget in the tab order.

You might want to read the following about that subject:

For more information on wxPython's key and char events, see the following:

OTHER TIPS

1.For the tabbing to work at all, the window or individual panel you plonk controls/wigits on has to have as part of its style flag the following: wxTAB_TRAVERSAL ie;

class MyPanel(wx.Panel):
    def __init__(self, parent,id):
        wx.Panel.__init__(self, parent, id, wx.DefaultPosition,wx.DefaultSize,
                         wx.RAISED_BORDER|wx.TAB_TRAVERSAL)

2. The tab order is set by the order you add controls to the panel or frame.

3) Tabbing order also seems to be dependent in the order widgets are created. I assume this is due to widget ID numbers. Order of addition to sizers/panels did not seem to help me with .

4) Here's a little Demofor setting tab order once you have the controls set up:

order = (control1, control2, control3, ...)
for i in xrange(len(order) - 1):
   order[i+1].MoveAfterInTabOrder(order[i])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top