Search code examples
wxpythonwxwidgets

How do I bind wxScintilla commands to pageup and pagedown in wxScintilla?


I'm using wxScintilla from wxPython, and I cannot find STC_KEY_PAGEUP or STC_KEY_PAGEDOWN in wx.stc. How do I bind a keyboard shortcut to the page up or page down keys?


For example, to bind the return key to the newline command I would write:

wxscintilla_ctrl.CmdKeyAssign(STC_KEY_RETURN, STC_SCMOD_NORM, STC_CMD_NEWLINE)

But there is no STC_KEY_* for page up and page down. How can I call CmdKeyAssign() to bind page up and page down without an STC_KEY_PAGEUP or STC_KEY_PAGEDOWN in wx.stc?


Solution

  • I trust I've not got the wrong end of the stick with your question but to activate a callback on PgUp or PgDn, you simply bind to the wx.EVT_KEY_UP or other key event as normal. Then check which key was used.

    for Key assignment/re-assignment with CmdKeyAssign() the names of PgUp and PgDn, confusingly, become Prior and Next. See below:

    import wx
    import wx.stc
    class MyApp(wx.App):
        def OnInit(self):
            self.frame = MenuFrame(None, title="STC Test")
            self.SetTopWindow(self.frame)
            self.frame.Show()
    
            return True
    
    ID_READ_ONLY = wx.NewId()
    
    class MenuFrame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(MenuFrame, self).__init__(*args, **kwargs)
    
            # Attributes
            self.panel = wx.Panel(self)
            self.txtctrl = wx.stc.StyledTextCtrl(self.panel,
                                       style=wx.TE_MULTILINE)
    
            # Layout
            sizer = wx.BoxSizer(wx.HORIZONTAL)
            sizer.Add(self.txtctrl, 1, wx.EXPAND)
            self.panel.SetSizer(sizer)
            self.CreateStatusBar() # For output display
    
            # Setup the Menu
            menub = wx.MenuBar()
    
            # File Menu
            filem = wx.Menu()
            filem.Append(wx.ID_NEW, "New\tCtrl+N")
            filem.Append(wx.ID_OPEN, "Open\tCtrl+O")
            filem.Append(wx.ID_SAVE, "Save\tCtrl+S")
            filem.Append(wx.ID_SAVEAS, "Save_As\tCtrl+Shift+S")
            menub.Append(filem, "&File")
    
            # Edit Menu
            editm = wx.Menu()
            editm.Append(wx.ID_UNDO, "Undo\tCtrl+Z")
            editm.Append(wx.ID_REDO, "Redo\tCtrl+Shift+Z")
            editm.Append(wx.ID_COPY, "Copy\tCtrl+C")
            editm.Append(wx.ID_CUT, "Cut\tCtrl+X")
            editm.Append(wx.ID_PASTE, "Paste\tCtrl+V")
            editm.Append(wx.ID_SELECTALL, "SelectAll\tCtrl+A")
            editm.AppendSeparator()
            editm.Append(ID_READ_ONLY, "Read Only",
                         kind=wx.ITEM_CHECK)
            menub.Append(editm, "E&dit")
    
            self.SetMenuBar(menub)
    
            # Event Handlers
            self.Bind(wx.EVT_MENU, self.OnMenu)
            self.txtctrl.Bind(wx.EVT_KEY_UP, self.OnKey)
    
            # optionally re-assigning keys to commands
            # PageUp without a modifier key to move 1 word right
            self.txtctrl.CmdKeyAssign(wx.stc.STC_KEY_PRIOR, 0, wx.stc.STC_CMD_WORDRIGHT)
            # PageDown without a modifier key to move 1 word left
            self.txtctrl.CmdKeyAssign(wx.stc.STC_KEY_NEXT, 0, wx.stc.STC_CMD_WORDLEFT)
            # Ctrl + F1 key delete line
            self.txtctrl.CmdKeyAssign(wx.WXK_F1, wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_LINEDELETE)
    
        def OnKey(self, event):
            keycode = event.GetKeyCode()
            if keycode == wx.WXK_PAGEUP:
                print ("Up")
            if keycode == wx.WXK_PAGEDOWN:
                print ("Down")
            event.Skip()
    
        def OnMenu(self, event):
            """Handle menu clicks"""
            evt_id = event.GetId()
            actions = { wx.ID_COPY  : self.txtctrl.Copy,
                        wx.ID_CUT   : self.txtctrl.Cut,
                        wx.ID_PASTE : self.txtctrl.Paste,
                        wx.ID_UNDO : self.txtctrl.Undo,
                        wx.ID_REDO : self.txtctrl.Redo,
                        wx.ID_SELECTALL : self.txtctrl.SelectAll}
            action = actions.get(evt_id, None)
            if action:
                action()
            elif evt_id == ID_READ_ONLY:
                # Toggle enabled state
                self.txtctrl.Enable(not self.txtctrl.Enabled)
            elif evt_id == wx.ID_OPEN:
                dlg = wx.FileDialog(self, "Open File", style=wx.FD_OPEN)
                if dlg.ShowModal() == wx.ID_OK:
                    fname = dlg.GetPath()
                    handle = open(fname, 'r')
                    self.txtctrl.SetValue(handle.read())
                    handle.close()
            else:
                event.Skip()
    
    
    if __name__ == "__main__":
        app = MyApp(False)
        app.MainLoop()