Reputation: 33
I'm writing a calculator application on MS Windows 8.1 using wxPython-Phoenix
in which I'd like the calculation to be performed as soon as the user enters a value into one of the parameter fields. To achieve that I'm using wx.EVT_KILL_FOCUS
generated by any parameter field to generate a command event which triggers the calculation method. Everything works fine but the appearance of the caret in the parameter fields (implemented by TextCtrl widgets).
After setting the focus either by the Tab key or the mouse on a certain field and moving it (again by the Tab key or the mouse) to a different field - the caret is gone from the TextCtrl widget never to return! when you call the GetCaret() method on that TextCtrl widget the return value is None.
See attached example. The widget still accepts input and displays it but without a caret.
How can I restore the caret in the right position? or not lose it in the first place?
I've tried setting a new caret in the TextCtrl but it does not follow the text input. Since the application is ment to be intensely interactive, I want the triggering event to be the lost focus and not a button (to minimize the number of clicks)
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(MyFrame, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
# setting up the Input panel
panel = wx.Panel(self)
self.lbl1 = wx.StaticText(panel,wx.ID_ANY,'Some Text:')
self.txt1 = wx.TextCtrl(panel,wx.ID_ANY,style=wx.TE_RIGHT)
self.lbl2 = wx.StaticText(panel,wx.ID_ANY,'Some Other Text:')
self.txt2 = wx.TextCtrl(panel,wx.ID_ANY,style=wx.TE_RIGHT)
infgsz = wx.FlexGridSizer(2,2,15,15)
infgsz.AddMany([(self.lbl1,0,wx.ALIGN_LEFT),\
(self.txt1,0,wx.ALIGN_LEFT),\
(self.lbl2,0,wx.ALIGN_LEFT),\
(self.txt2,0,wx.ALIGN_LEFT)])
self.txt1.Bind(wx.EVT_KILL_FOCUS,self.OnInput)
self.txt2.Bind(wx.EVT_KILL_FOCUS,self.OnInput)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(infgsz, flag= wx.EXPAND | wx.ALL, border=15)
panel.SetSizer(box)
self.SetSize((280, 140))
self.SetTitle('TextCtrl Demo')
self.Centre()
def OnInput(self, e):
if e.GetId() == self.txt1.GetId():
self.lbl2.SetForegroundColour(wx.ColourDatabase().Find('RED'))
self.lbl1.SetForegroundColour(wx.ColourDatabase().Find('BLACK'))
else:
self.lbl1.SetForegroundColour(wx.ColourDatabase().Find('BLUE'))
self.lbl2.SetForegroundColour(wx.ColourDatabase().Find('BLACK'))
self.Refresh()
def main():
app = wx.App()
frame = MyFrame(None)
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
The above application displays 2 lines of text. In each line there is a label (wx.StaticText
widget) on the left and a TextCtrl
widget on the right. when you enter text into the TextCtrl
widget of either line and move the focus to the other TextCtrl
widget the corresponding label foreground color (the text color) changes to RED or BLUE and the other label changes to BLACK. However, without any seen reason, the caret disappears from the top TextCtrl
widget and never returns to it! (On MS Windows 8.1 at least).
Upvotes: 3
Views: 636
Reputation: 22688
The documentation explicitly tells you
The focus event handlers should almost invariably call wxEvent::Skip() on their event argument to allow the default handling to take place.
and goes on to explain that not doing it may result in various problems -- such as the one you're observing.
Add e.Skip()
to your event handler to fix it.
Upvotes: 3