¿Cómo cambiar la posición del cursor de wxRichTextCtrl en el controlador de eventos?
Pregunta
Tengo un RichTextCtrl en mi aplicación, que tiene un controlador para EVT_KEY_DOWN
. El código que se ejecuta es el siguiente:
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 es mi RichTextCtrl.
Esto es lo que me gustaría que hiciera:
-
en cada pulsación de tecla, agregue la tecla al control (que es el comportamiento predeterminado)
-
mueve el cursor al comienzo del control, primera posición
Esto es lo que realmente hace:
-
agrega la clave al control
-
Inspeccioné la posición del cursor, y el depurador informa que está ubicado en 0,0 pero en el control, parpadea en la posición actual (que es la posición antes de presionar una tecla + 1)
¿Ves algo mal aquí? Debe haber algo que estoy haciendo mal.
Solución
Aparentemente, hay dos problemas con su código:
-
Escuchas en
EVT_KEY_DOWN
, que probablemente se maneja antes deEVT_TEXT
, cuyo controlador predeterminado establece la posición del cursor. -
Modificas el objeto
Caret
en lugar de usar el métodoSetInsertionPoint
, que mueve el cursor y hace que aparezca el siguiente carácter en un lugar determinado.
Entonces, el ejemplo de trabajo (lo probé y funciona como a usted le gustaría) sería:
# 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 : si desea que el texto se agregue al final, pero el cursor permanezca al principio (ver comentarios), puede aprovechar el hecho de que EVT_KEY_DOWN
se maneja antes de EVT_TEXT
(que a su vez se maneja después de la adición de caracteres). Entonces el orden de los eventos es:
- manejar
EVT_KEY_DOWN
- agregar carácter en el punto de inserción actual
- manejar
EVT_TEXT
Agregar un controlador de EVT_KEY_DOWN
que mueve el punto de inserción hasta el final justo antes de agregar el personaje hace el trabajo bastante bien. Entonces, además del código mencionado anteriormente, escriba:
# Somewhere in __init__:
self.rich.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
def onKeyDown(self, event):
self.rich.SetInsertionPointEnd()
event.Skip()
Por cierto, event.Skip ()
no invoca inmediatamente el siguiente controlador de eventos, solo pone un indicador en el objeto event
, para que el procesador de eventos sepa si para dejar de propagar el evento después de este controlador.