views:

516

answers:

1

I have a RichTextCtrl in my application, that has a handler for EVT_KEY_DOWN. The code that is executed is the following :


def move_caret(self):
    pdb.set_trace()
    self.rich.GetCaret().Move((0,0))
    self.Refresh()


def onClick(self,event):
    self.move_caret()
    event.Skip()

rich is my RichTextCtrl.

Here is what I would like it to do :

  • on each key press, add the key to the control ( which is default behaviour )

  • move the cursor at the beginning of the control, first position

Here's what it actually does :

  • it adds the key to the control

  • I inspected the caret position, and the debugger reports it's located at 0,0 but on the control, it blinks at the current position ( which is position before I pressed a key + 1 )

Do you see anything wrong here? There must be something I'm doing wrong.

+3  A: 

Apparently, there are two problems with your code:

  1. You listen on EVT_KEY_DOWN, which is probably handled before EVT_TEXT, whose default handler sets the cursor position.

  2. You modify the Caret object instead of using SetInsertionPoint method, which both moves the caret and makes the next character appear in given place.

So the working example (I tested it and it works as you would like it to) would be:

# Somewhere in __init__:
    self.rich.Bind(wx.EVT_TEXT, self.onClick)

def onClick(self, event):
    self.rich.SetInsertionPoint(0) # No refresh necessary.
    event.Skip()


EDIT: if you want the text to be added at the end, but the cursor to remain at the beginning (see comments), you can take advantage of the fact that EVT_KEY_DOWN is handled before EVT_TEXT (which in turn is handled after character addition). So the order of events is:

  1. handle EVT_KEY_DOWN
  2. add character at current insertion point
  3. handle EVT_TEXT

Adding a handler of EVT_KEY_DOWN that moves the insertion point to the end just before actually adding the character does the job quite nicely. So, in addition to the code mentioned earlier, write:

# Somewhere in __init__:
    self.rich.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)

def onKeyDown(self, event):
    self.rich.SetInsertionPointEnd()
    event.Skip()

By the way, event.Skip() does not immediately invoke next event handler, it justs sets a flag in the event object, so that event processor knows whether to stop propagating the event after this handler.

DzinX
I would like the character to appear normally, not at position 0. I would like to move the caret to position 0 after. Can you show me how to do that ? I tried to put event.Skip first and call SetInsertionPoint after, but I get the same behaviour.
Geo