Search code examples
user-interfacewxpythonwxwidgetsqr-code

WxPython: How would I programatically move the curser to (select) a specific Text Box, triggered by a button press?


This question is the last piece in a larger problem I am trying to solve. I am currently trying to implement a QR scanner to fill multiple fields in a UI. The UI that I want for this is a button titled 'Scan QR Code', which puts the software in a mode where it is listening for the QR scanner, which then can scan and autofill all those fields.

My current implementation for this is to have an invisible text box, to which the cursor gets moved when the button is pressed. That box then waits for a EVT_TEXT_ENTER event, triggered when the QR scanner enters text. That text is then parsed into the relevant visible text boxes.

The only part I am not sure how to do is to programmatically move the cursor to the textbox (when the button is pressed)

I would expect there to be a method of the TextCtrl object to select it or move the cursor to it, but I cannot find that in documentation.


Solution

  • A quick mock up of what @John Hanley is referring to, where we define the hidden textctrl as size=(0,0), rather than actually hiding it with .Hide() as that causes errors when you try to use it for input.
    Or at least it does on Linux using Gtk.

    import wx
    
    class MyFrame(wx.Frame):
    
        def __init__(self, title="Scan"):
    
            wx.Frame.__init__(self, None, title=title)
    
            panel = wx.Panel(self)
            self.othertxt = wx.TextCtrl(panel)
            self.othertxt.SetHint("other form items")
            self.hiddentxt = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER, size=(0,0))
            self.hiddentxt.Bind(wx.EVT_TEXT_ENTER, self.OnEnter)
            self.button = wx.Button(panel, label="Start")
            self.button.Bind(wx.EVT_BUTTON, self.OnButton)
            self.processedtxt = wx.TextCtrl(panel)
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.othertxt, 0, wx.EXPAND)
            sizer.Add(self.hiddentxt, 0, wx.EXPAND)
            sizer.Add(self.button, 0, wx.EXPAND)
            sizer.Add(self.processedtxt, 0, wx.EXPAND)
            panel.SetSizer(sizer)
    
        def OnEnter(self, event):
            self.processedtxt.SetValue("QR code input "+self.hiddentxt.GetValue())
            self.hiddentxt.Clear()
            self.button.SetFocus()
    
        def OnButton(self, event):
            self.processedtxt.Clear()
            self.hiddentxt.SetFocus()
    
    if __name__ == '__main__':
        app = wx.App()
        frm = MyFrame()
        frm.Show()
        app.MainLoop()