Reputation: 2449
Morning, I would like to call a function in my GUI in the event that the content of a TextCtrl is changed. Only after the user leaves the TextCtrl object though, not during editing.
Please can you help me find the right event handler to use, I'm very new to wxpython and I can't even find a list of allowable events.
Many thanks
Upvotes: 0
Views: 919
Reputation: 1090
I did a listener that bind the keyboard events and set the input only to be a numerical value on the TxtCtrl, you can change this listener to the behaviour you prefer (:
Usage:
self.__MyTxtCtrl.Bind(wx.EVT_CHAR, self.__on_change_text_check_is_int_value)
def __on_change_text_check_is_float_value(self, evt):
KeyboardEventUtils.on_change_text_check_is_int_value(self, evt)
This is the listener in a singleton utils class:
from pyglet.window import key
from Utils.NumberUtils import NumberUtils
ENTRY_ID = "id"
ENTRY_KEY_EVENT = "keyEvent"
ENTRY_SELECTION_EVENT = "selectionEvent"
MASK_STARTED_RIGHT_SELECTION = 1
MASK_STARTED_LEFT_SELECTION = -1
class KeyboardEventUtils(object):
__mLastEvt = {}
def on_change_text_check_is_float_value(self, evt):
txt = evt.GetEventObject()
strng = txt.GetValue()
rawKey = evt.GetRawKeyCode()
modifiers = evt.GetModifiers()
if KeyboardEventUtils.__mLastEvt != None and len(KeyboardEventUtils.__mLastEvt) > 0 and KeyboardEventUtils.__mLastEvt[ENTRY_ID] != txt.GetId():
self._mLastEvt = {}
if chr(rawKey).isnumeric() or (rawKey == key.PERIOD and not chr(rawKey) in strng and len(strng) > 0) or (rawKey == key.MINUS and not chr(rawKey) in strng and (len(strng) == 0 or txt.GetInsertionPoint() == 0)):
pos = txt.GetInsertionPoint()
txt.SetValue(str(float(txt.GetValue()[:pos] + chr(rawKey) + txt.GetValue()[pos:])))
txt.SetInsertionPoint(pos + 1)
elif (modifiers == 4 or modifiers == key.MOD_SHIFT) and rawKey == key.LEFT: # 4 (?) key.MOD_SHIFT (?)
pos = txt.GetInsertionPoint()
rng = list(txt.GetSelection())
if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]
if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_RIGHT_SELECTION:
rng[1] = rng[1] - 1
else:
KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_LEFT_SELECTION
rng[0] = rng[0] - 1
txt.SetSelection(rng[0], rng[1])
elif (modifiers == 4 or modifiers == key.MOD_SHIFT): # 4 (?) key.MOD_SHIFT (?)
pos = txt.GetInsertionPoint()
rng = list(txt.GetSelection())
if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]
if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_LEFT_SELECTION:
rng[0] = rng[0] + 1
else:
KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_RIGHT_SELECTION
rng[1] = rng[1] + 1
txt.SetSelection(rng[0], rng[1])
elif rawKey == key.LEFT:
rng = list(txt.GetSelection())
if rng[0] != rng[1]:
txt.SetInsertionPoint(rng[0])
else:
txt.SetInsertionPoint(txt.GetInsertionPoint() - 1)
elif rawKey == key.RIGHT:
rng = list(txt.GetSelection())
if rng[0] != rng[1]:
txt.SetInsertionPoint(rng[1])
else:
txt.SetInsertionPoint(txt.GetInsertionPoint() + 1)
elif rawKey == key.UP or rawKey == key.DOWN:
pass
elif rawKey == key.BACKSPACE:
pos = txt.GetInsertionPoint()
if txt.GetStringSelection() == "":
txt.SetValue(txt.GetValue()[:pos-1] + txt.GetValue()[pos:])
txt.SetInsertionPoint(pos - 0x1)
else:
r = txt.GetSelection()
txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
txt.SetInsertionPoint(pos)
elif rawKey == key.DELETE:
pos = txt.GetInsertionPoint()
if txt.GetStringSelection() == "":
txt.SetValue(txt.GetValue()[:pos] + txt.GetValue()[pos+1:])
else:
r = txt.GetSelection()
txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
txt.SetInsertionPoint(pos)
elif modifiers == key.MOD_CTRL and rawKey == key.A:
txt.SelectAll()
else:
KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
return False
KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
return True
SOURCE of INFOs key MODULE Python
Upvotes: 0
Reputation: 3218
You can bind the TextCtrl
to wx.EVT_TEXT
to capture changes to the value and wx.EVT_KILL_FOCUS
to trigger an even when the focus changes. Alternatively you could bind it to wx.EVT_SET_FOCUS
and save the current TextCtrl
value and also bind to it wx.EVT_KILL_FOCUS
to and compare the new value to see if it's changed.
------- EDIT -------
WxFormBuilder is fantastic tool for quickly creating basic UIs. It will also show you every event that you can bind to a widget by clicking on the 'events'` tab.
Upvotes: 0