Search code examples
pythonpyqtkeyboard-shortcutspyqt5qscintilla

How to assign QScintilla shortcuts


I'm trying to implement shortcuts to my editor, but I haven't had any success so far.

I'd like to override some of the default QScintilla shortcuts. I have read this answer, but I'm not sure if this helps to solve my problem.

I have also read the Scintilla (SCI_ASSIGNCMDKEY) documentation, but I don't know how I'm supposed to use it in a pythonic way.

To make it clear:

  1. I'd like to override the QScintilla shortcut Ctrl+L and use my custom solution (assign it to one of my functions).

  2. I'd like to assign the command SCI_LINEDELETE to the shortcut Ctrl+D.

This is my idea:

    from PyQt5.Qsci import QsciScintilla
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    import sys

    class mainWindow(QMainWindow):
        def __init__(self, parent = None):
            super(mainWindow, self).__init__(parent)
            self.initUI()

        def initUI(self):
            self.center_window = centerWindow(parent=self)
            self.setCentralWidget(self.center_window) 

    class centerWindow(QWidget):
        def __init__(self, parent=None):
            super(centerWindow, self).__init__(parent)

            self.hhEditor_te = QsciScintilla()

            vbox = QVBoxLayout(self)
            vbox.addWidget(self.hhEditor_te)
            self.setLayout(vbox)

            # 1)
            # assign a key binding to this function
            # self.my_shortcut

            # 2)
            # assign a key binding to the QScintilla command
            # SCI_LINEDELETE

        def my_shortcut(self):
            pass
            # my custom shortcut function

    if __name__ == '__main__':
        app = QApplication.instance()
        if app is None:
            app = QApplication(sys.argv)
        else:
            print('QApplication instance already exists: %s' % str(app))

        ex = mainWindow()
        ex.setGeometry(0,100,1500,600)
        ex.show()
        sys.exit(app.exec_())

Solution

  • QScintilla already provides the QsciCommandSet and QsciCommand classes for handling shortcuts for the internal editor commands. You can also use QShortcut to create shortcuts for your own methods.

    class centerWindow(QWidget):
        def __init__(self, parent=None):
            ...
            commands = self.hhEditor_te.standardCommands()
    
            command = commands.boundTo(Qt.ControlModifier | Qt.Key_L)
            if command is not None:
                command.setKey(0) # clear the default
            command = commands.boundTo(Qt.ControlModifier | Qt.Key_D)
            if command is not None:
                command.setKey(0) # clear the default
    
            command = commands.find(QsciCommand.LineDelete)
            if command is not None:
                command.setKey(Qt.ControlModifier | Qt.Key_D)
    
            shortcut = QShortcut(Qt.ControlModifier | Qt.Key_L, self.hhEditor_te)
            shortcut.activated.connect(self.my_shortcut)
            ...
    
        def my_shortcut(self):
            print('Ctrl+L')