# In def __init__
self.qtyField.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
# Then ...
def OnFocus(self, event): print ("Got a focus event") self.focusWindow = event.GetWindow() event.Skip()
# And ...
def OnOne(self, event): # wxGlade: MyFrame.<event_handler> self.focusWindow.AppendText('1') event.Skip()
This approach is really over-complicated. All you need to do is to
store the wx.TextCtrl as an attribute of your instance and reference it
later.
self.aTextCtrl = wx.TextCtrl(...)
However, I am still a bit confused about the Python handle / unmutable object / mutable list concept. In particular, how I can record the whatever_it_is that is returned from event.GetWindow()?
This is what I have tried:
# In def __init__
self.qtyField.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
# Then ...
def OnFocus(self, event):print ("Got a focus event")self.focusWindow = event.GetWindow()event.Skip()
# And ...
def OnOne(self, event): # wxGlade: MyFrame.<event_handler>self.focusWindow.AppendText('1')event.Skip()
However, self.focusWindow only gets local scope (I think), so the self.focusWindow in OnOne is not the same as in OnFocus.
-- Tim Roberts, ti...@probo.com Providenza & Boekelheide, Inc.
Here's the way I think about it. You have objects, and you have namespaces. The world of objects is just a big cloud of "things" that have a type and a value, but they have no names.
....
However, self.focusWindow only gets local scope (I think), so the self.focusWindow in OnOne is not the same as in OnFocus.
That's not true. self.focusWindow is a member variable, just like member variables in C++. All the events for this window will get passed the same "self" object (just like "this" in C++), so self.focusWindow will refer to whatever object tucked in there last.
James's suggestion was to skip using the focusWindow hack, and instead just refer to self.qtyField in your OnOne handler. If you know which window fired the event, then just use your local reference. He just happened to use a different variable name in his description.
def OnNumber(self, event): if self.focusWindow is not None: self.focusWindow.AppendText(event.GetEventObject().GetLabel())
event.Skip()
def OnClear(self, event): if self.focusWindow is not None: self.focusWindow.Clear()
event.Skip()
def OnFocus(self, event): print ("Got a focus event")
if event.GetEventObject() == self.nameField: self.focusWindow = None else: self.focusWindow = event.GetEventObject()
event.Skip()
Actually, I'd be inclined to use a list of valid focus objects, as I created them, such as:focusableWindows = [self.xvalue,self.yvalue,self.zvalue]Then later, you can say:if event.GetEventObject() in focusableWindows:self.focusWindow = event.GetEventObject()So you can always be pointing to a valid focus window, unless you really want to de-focus the pointer.
The GUI the OP has built has its own "Virtual Keyboard" (calculator style) and he wants to direct
the keyed input to selected fields.
A different approach may be to simply have the virtual keyboard
act like a regular keyboard, so either can be used for the data input in any field, using the built in
mechanism, rather than the way he's doing it now.
Simulating standard keyboard input from GUI events could have many benefits.
(I too, questioned using focus to do this, but instead rather highlighting the changing field with color or
a check-box as you suggest, but there'd still be the selection process, which focus seems to already
to do.)
I am not sure what is wrong with using focus? When a wx.TextCtrl has focus it flashes a cursor at the edit point - which to me seems a reasonable indication that that control will receive user input.
On Tuesday, September 26, 2017 at 8:16:12 PM UTC+1, Rufus wrote:The GUI the OP has built has its own "Virtual Keyboard" (calculator style) and he wants to direct
the keyed input to selected fields.Yes, that is exactly it.A different approach may be to simply have the virtual keyboard
act like a regular keyboard, so either can be used for the data input in any field, using the built in
mechanism, rather than the way he's doing it now.
Simulating standard keyboard input from GUI events could have many benefits.Hmm, yes that is certainly a neat way of tackling the problem. I haven't tried this yet, but in wxWidgets C++, events propagate upwards so I am not sure whether you can wx.PostEvent to a form and have the text appear in a child window.
either way, as soon as the user clicks on a button on the "number pad" -- that ctr will lose focus.I suspect it will be a bit confusing for the user for the input to go to the last item that happened to have focus, if, in fact, it was one of the controls that can receive input.On the other hand, I'm not seeing it in action, maybe it's more obvious than it sounds.But if you keep "the last control with focus" approach, you might want to have a stronger visual indicator of what the active control is -- so once someone clicks on it, it receives focus, it also get highlighted or something, and then as they go and click on the number pad the highlight remains.
Second, sending a wx event will not be the same thing as a native widget getting a native message that it acts upon by adding a character to the control or whatever. wx events are only sent to the wx layers of the software stack, it is only when wx is translating a native message to an event that it can affect things, and that is only to the point of telling the native control whether the event has been handled in the wx layers or not.
Something I haven't seen mentioned yet is the wx.UIActionSimulator. It's not perfect but it might be enough for what you need.
You will still need to ensure the focus is in the right place however before the simulator will be able to stuff keystrokes into the message queue, so you'll still need to keep track of the last focused editable widget, because as Chris said, clicking on the buttons for your simulated keyboard will move the focus to the button.
Another approach, which I am using for a touch screen application, is to have a calculator keyboard withits own display/text area. All keypresses affect that display area, and I added the buttons [set x] [set y], etcto copy that data into the selected field positions, after the data entry was complete.