Hi. I am using Fedora 32, wxPython 4.1.1 on Python3.8.7.
I can not seem to be able to figure out how to capture text paste (ctrl-v) in a RichTextCtrl
.
The EVT_TEXT_PASTE
is not fired by RichTextCtrl
and I did not find any other similar event.
Other events are fired any time some text is written and not just when something is pasted.
I decided to try to use EVT_KEY_UP
and the wx.KeyEvent
because it allows detection of ctrl key being held down and also gives some key codes. I wanted to use it to detect when ctrl and ‘v’ key are pressed.
Unfortunately I do not understand how to use wx.KeyCode
. The code given by the event.GetKeyCode()
is the ascii character number of the key, but for example the wx.WXK_CONTROL_V
is 22
while ‘v’ is 86
and ctrl is 308
, I could not produce the 22 in any way even when pressed together.
Is there a better way of detecting text paste in RichTextCtrl
?
What are the WXK codes and how to use them?
Here is some sample code to experiment with:
It prints the key code, ctrl key state and the value of wx.WXK_CONTROL_V
on every key up.
import wx
import wx.richtext as rt
class RichTextFrame(wx.Frame):
def __init__(self, *args, **kw):
wx.Frame.__init__(self, *args, **kw)
self.rtc = rt.RichTextCtrl(self, style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER)
self._main_sizer = wx.BoxSizer(wx.VERTICAL)
self._controls_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(self._main_sizer)
self._bold_button = wx.Button(self, -1, 'bold')
self._controls_sizer.Add(self._bold_button)
self._main_sizer.Add(self.rtc, 1, flag=wx.EXPAND)
self._main_sizer.Add(self._controls_sizer)
self.Bind(wx.EVT_BUTTON, self._change_bold, self._bold_button)
self.Bind(wx.EVT_MENU, self._forward_event)
self.rtc.Bind(wx.EVT_KEY_UP, self._up, self.rtc)
self.rtc.AppendText('Sample text')
def _up(self, event: wx.KeyEvent) -> None:
"""
Handle key up events.
:param event: Used for getting key info.
:return: None
"""
event.Skip()
print('event key code: ', event.GetKeyCode())
print('ctrl: ', event.ControlDown())
print(wx.WXK_CONTROL_V)
print(self.rtc.GetValue())
def _change_bold(self, evt: wx.CommandEvent) -> None:
"""
Make text bold and vice versa.
:param evt: Not used
:return: None
"""
self.rtc.ApplyBoldToSelection()
def _forward_event(self, evt):
self.rtc.ProcessEvent(evt)
class MyApp(wx.App):
"""
Main class for running the gui
"""
def __init__(self):
wx.App.__init__(self)
self.frame = None
def OnInit(self):
# Required for copy paste to work and retain text attributes
rt.RichTextBuffer.AddHandler(rt.RichTextXMLHandler())
self.frame = RichTextFrame(None, -1, "RichTextCtrl", size=(400, 400), style=wx.DEFAULT_FRAME_STYLE)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
Thanks