Skip to content
Browse files
[console] Allow breaking execution of scripts via Ctrl-C
This allows (in some circumstances) scripts running in the console
to be halted via the Ctrl (or Meta) + C shortcut.

(It's only possible to catch and abort when the script is printing
outputs to the console - because this triggers
QCoreApplication.processEvents() calls. Without these calls the
whole QGIS application is unresponsive during script execution
and there's no ability to even catch a shortcut in order to
halt the execution.

Still, even with this limitation it's handy to be able to
break out of lengthy:

for f in iface.activeLayer().getFeatures():

  • Loading branch information
nyalldawson committed Jan 29, 2018
1 parent d2244b4 commit f6269c41da28b2c992e858154edbbfad6050455d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
@@ -39,6 +39,7 @@ def __init__(self, shellOut, out=None, style=None):
self.sO = shellOut
self.out = None = style
self.fire_keyboard_interrupt = False

def write(self, m):
if == "_traceback":
@@ -62,6 +63,10 @@ def write(self, m):
if != "_traceback":

if self.fire_keyboard_interrupt:
self.fire_keyboard_interrupt = False
raise KeyboardInterrupt

def move_cursor_to_end(self):
"""Move cursor to end of text"""
line, index = self.get_end_pos()
@@ -378,9 +378,16 @@ def keyPressEvent(self, e):
if not self.is_cursor_on_edition_zone() or startLine < endLine:
# allow copying and selecting
if e.modifiers() & (Qt.ControlModifier | Qt.MetaModifier):
if e.key() in (Qt.Key_C, Qt.Key_A):
if e.key() == Qt.Key_C:
# only catch and return from Ctrl-C here if there's a selection
if self.hasSelectedText():
QsciScintilla.keyPressEvent(self, e)
elif e.key() == Qt.Key_A:
QsciScintilla.keyPressEvent(self, e)
# allow selection
if e.modifiers() & Qt.ShiftModifier:
if e.key() in (Qt.Key_Left, Qt.Key_Right, Qt.Key_Home, Qt.Key_End):
@@ -389,6 +396,11 @@ def keyPressEvent(self, e):
# all other keystrokes get sent to the input line

if e.modifiers() & (Qt.ControlModifier | Qt.MetaModifier) and e.key() == Qt.Key_C and not self.hasSelectedText():
# keyboard interrupt
sys.stdout.fire_keyboard_interrupt = True

line, index = self.getCursorPosition()
cmd = self.text(line)

@@ -602,12 +614,14 @@ def write(self, txt):

def writeCMD(self, txt):
sys.stdout.fire_keyboard_interrupt = False
if len(txt) > 0:
getCmdString = self.text()
prompt = getCmdString[0:4]
sys.stdout.write(prompt + txt + '\n')

def runsource(self, source, filename='<input>', symbol='single'):
sys.stdout.fire_keyboard_interrupt = False
hook = sys.excepthook
def excepthook(etype, value, tb):

0 comments on commit f6269c4

Please sign in to comment.