python-3.xwxpythonkeydownonkeydownwxtextctrl

wx.EVT_KEY_DOWN - evt.skip() doesn't work


I created a gui in wxpython. I tried to use wx.EVT_KEY_DOWN. When I press a key, I want to know if the key changed the messageTxt (It was't a key such as right, shift, alt etc...). I prints the messageTxt before and after the evt.Skip() but it doen't changes, only in the second char i can see the last changes. Someone know how do I get the new messageTxt after the evt.Skip()? By that, I could compare the text before the skipping and after and get the result it there was a change. Here is some code that explaines the problem.

import wx
from wx.stc import StyledTextCtrl


def On_KeyDown(evt):
    x, y = messageTxt.GetSelection()
    # If something is selected, de-select it
    if x != y:
        messageTxt.SetEmptySelection(y)
    else:
        print("Before skipping", messageTxt.GetText())
        evt.Skip()
        print("After skipping", messageTxt.GetText())


app = wx.App()
frame = wx.Frame(None, -1, title='2', pos=(0, 0), size=(500, 500))
frame.Show(True)
messageTxt = StyledTextCtrl(frame, id=wx.ID_ANY, pos=(0, 0), size=(100 * 3, 100),
                            style=wx.TE_MULTILINE, name="File")

messageTxt.Bind(wx.EVT_KEY_DOWN, On_KeyDown)

app.SetTopWindow(frame)
app.MainLoop()

Solution

  • Your problem is that EVT_KEY_DOWN is working.
    The key down event occurs before the key itself is recognised.
    You should check the EVT_KEY_UP and then test for your special keys.

    import wx
    from wx.stc import StyledTextCtrl
    
    def On_KeyDown(evt):
        x, y = messageTxt.GetSelection()
        # If something is selected, de-select it
        if x != y:
            messageTxt.SetEmptySelection(y)
        else:
            evt.Skip()
    
    def On_KeyUp(evt):
        print("Text :", messageTxt.GetText())
        k = evt.GetKeyCode()
        if k in (wx.WXK_SHIFT,wx.WXK_ALT,wx.WXK_CONTROL,wx.WXK_DOWN):
            print('Special key')
        evt.Skip()
    
    app = wx.App()
    frame = wx.Frame(None, -1, title='2', pos=(0, 0), size=(500, 500))
    frame.Show(True)
    messageTxt = StyledTextCtrl(frame, id=wx.ID_ANY, pos=(0, 0), size=(100 * 3, 100),
                                style=wx.TE_MULTILINE, name="File")
    
    messageTxt.Bind(wx.EVT_KEY_DOWN, On_KeyDown)
    messageTxt.Bind(wx.EVT_KEY_UP, On_KeyUp)
    
    app.SetTopWindow(frame)
    app.MainLoop()
    

    However you will need to seperate these functions into wx.EVT_KEY_UP and wx.EVT_KEY_DOWN functions or they will work at cross purposes to each other i.e. either the key changing test will work and the selection fails or vice-versa.

    You may be misunderstanding wx.event.Skip()

    Skip(self, skip=True) This method can be used inside an event handler to control whether further event handlers bound to this event will be called after the current one returns.

    Without Skip (or equivalently if Skip(false) is used), the event will not be processed any more. If Skip(true) is called, the event processing system continues searching for a further handler function for this event, even though it has been processed already in the current handler.

    In general, it is recommended to skip all non-command events to allow the default handling to take place. The command events are, however, normally not skipped as usually a single command such as a button click or menu item selection must only be processed by one handler.