Intercept and modify KeyEvents?

I have a TextCtrl for which I’m trying to intercept EVT_CHAR events and modify them so that they are uppercase.
The handler seems to be functioning properly. After it is modified the event.GetUnicodeKey() method returns the proper upper-case code, but the TextCtrl still gets the lower-case characters.
Am I doing something obviously wrong here?

class MyPanel(wx.Panel):
def init(self, parent):
wx.Panel.init(self, parent)

    wx.StaticText(self, label="Edit Control:", pos=(10,10))
    self.edit = wx.TextCtrl(self, pos=(150, 10), size=(140,-1))
    self.edit.Bind(wx.EVT_CHAR, self.OnChar)

def OnChar(self, event):
    char = unichr(event.GetUnicodeKey())
    upper_char = char.upper()
    if upper_char != char:
        event.SetUnicodeKey(ord(upper_char))
    event.Skip()

Try without the event.Skip() as you are handling it already.

Regards,

Dietmar

···

On 6/7/17 8:11 PM, cbeytas wrote:

I have a TextCtrl for which I'm trying to intercept EVT_CHAR events and modify them so that they are uppercase.
The handler seems to be functioning properly. After it is modified the event.GetUnicodeKey() method returns the proper upper-case code, but the TextCtrl still gets the lower-case characters.

P.S.: sorry: add the character to the text control instead of using event.SetUnicodeKey(...)

Right. It works if I do:
start, stop = textCtrl.GetSelection()
textCtrl.Replace(start, stop, upper_char)
event.Skip(False)

I’m not confident that would cover all possible cases, cross-platform. I’m just wondering why modifying the event doesn’t work.
Perhaps something I don’t understand with how events are processed? Maybe the event handler is receiving a clone and not the actual event?
I’ve tried to generate another wx.KeyEvent with the upper case character and posting that to the TextCtrl but that didn’t work either.
I’ve also tried cloning the event but seems that the event.Clone() method doesn’t work at all.

···

On Wednesday, 7 June 2017 16:18:32 UTC-4, Dietmar Schwertberger wrote:

P.S.: sorry: add the character to the text control instead of using
event.SetUnicodeKey(…)

Hi,

···

On Jun 7, 2017 8:41 PM, “cbeytas” cbeytas@hotmail.com wrote:

If you have a recent wxWidgets compiled for wxpython, this functionality is already present.

Just check the docs.

Thank you.

Right. It works if I do:
start, stop = textCtrl.GetSelection()
textCtrl.Replace(start, stop, upper_char)
event.Skip(False)

I’m not confident that would cover all possible cases, cross-platform. I’m just wondering why modifying the event doesn’t work.
Perhaps something I don’t understand with how events are processed? Maybe the event handler is receiving a clone and not the actual event?
I’ve tried to generate another wx.KeyEvent with the upper case character and posting that to the TextCtrl but that didn’t work either.
I’ve also tried cloning the event but seems that the event.Clone() method doesn’t work at all.

On Wednesday, 7 June 2017 16:18:32 UTC-4, Dietmar Schwertberger wrote:

P.S.: sorry: add the character to the text control instead of using
event.SetUnicodeKey(…)

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Check EVT_KEY_UP or maybe EVT_KEY_DOWN, as one of these events may be the one responsible for actually placing the character.

David

···

On Jun 7, 2017 8:16 PM, “Igor Korot” ikorot01@gmail.com wrote:

Hi,

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

On Jun 7, 2017 8:41 PM, “cbeytas” cbeytas@hotmail.com wrote:

If you have a recent wxWidgets compiled for wxpython, this functionality is already present.

Just check the docs.

Thank you.

Right. It works if I do:
start, stop = textCtrl.GetSelection()
textCtrl.Replace(start, stop, upper_char)
event.Skip(False)

I’m not confident that would cover all possible cases, cross-platform. I’m just wondering why modifying the event doesn’t work.
Perhaps something I don’t understand with how events are processed? Maybe the event handler is receiving a clone and not the actual event?
I’ve tried to generate another wx.KeyEvent with the upper case character and posting that to the TextCtrl but that didn’t work either.
I’ve also tried cloning the event but seems that the event.Clone() method doesn’t work at all.

On Wednesday, 7 June 2017 16:18:32 UTC-4, Dietmar Schwertberger wrote:

P.S.: sorry: add the character to the text control instead of using
event.SetUnicodeKey(…)

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Actually found a post which sort of explains that modifying KeyEvents won’t work.

http://wxpython-users.1045709.n5.nabble.com/Little-problems-tp2297400p2297405.html

This is a surprise to me since I can modify MouseEvents (ie. adjust the .X and .Y attributes) and they take effect and are propagated to controls.
Maybe difference between regular Events and CommandEvents.

cbeytas wrote:

Right. It works if I do:
     start, stop = textCtrl.GetSelection()
     textCtrl.Replace(start, stop, upper_char)
     event.Skip(False)

I'm not confident that would cover all possible cases, cross-platform.

I don't really feel like modifying key events is what you want to do here. Your goal - have all text in a wx.TextCtrl be uppercase. So what happens when a user pastes text into the control or you set the contents programmatically? You'll end up with a mix of upper and original case text.

Instead, it would probably be better to bind a wx.EVT_TEXT handler and, when the text in the control is changed, convert the whole thing to uppercase, restoring the selection if necessary. See this Stack Overflow question for an example:

···

--
James Scholes
http://twitter.com/JamesScholes

It’s all about aesthetics… Using EVT_TEXT can cause ugly flickering with the lower-case character showing
up for a split second before being replaced. Strangely enough it doesn’t happen on all machines.
I also want to block certain characters in the EVT_CHAR handler. EVT_TEXT happens after the character has been added to the control (possibly replacing the current selection). This wreaks havoc with the cursor position.
I already trap EVT_PASTE and manage clipboard pasting manually.

···

On Thursday, 8 June 2017 05:30:37 UTC-4, James Scholes wrote:

cbeytas wrote:

Right. It works if I do:

 start, stop = textCtrl.GetSelection()
 textCtrl.Replace(start, stop, upper_char)
 event.Skip(False)

I’m not confident that would cover all possible cases, cross-platform.

I don’t really feel like modifying key events is what you want to do
here. Your goal - have all text in a wx.TextCtrl be uppercase. So what
happens when a user pastes text into the control or you set the contents
programmatically? You’ll end up with a mix of upper and original case text.

Instead, it would probably be better to bind a wx.EVT_TEXT handler and,
when the text in the control is changed, convert the whole thing to
uppercase, restoring the selection if necessary. See this Stack
Overflow question for an example:

https://stackoverflow.com/questions/1241942/wxpython-textctrl-transform-to-uppercase


James Scholes

http://twitter.com/JamesScholes