diff --git a/IPython/frontend/qt/console/frontend_widget.py b/IPython/frontend/qt/console/frontend_widget.py index d9c4459..71fc00c 100644 --- a/IPython/frontend/qt/console/frontend_widget.py +++ b/IPython/frontend/qt/console/frontend_widget.py @@ -47,7 +47,7 @@ class FrontendHighlighter(PygmentsHighlighter): class FrontendWidget(HistoryConsoleWidget): - """ A Qt frontend for an IPython kernel. + """ A Qt frontend for a generic Python kernel. """ # Emitted when an 'execute_reply' is received from the kernel. @@ -63,7 +63,7 @@ class FrontendWidget(HistoryConsoleWidget): self._call_tip_widget = CallTipWidget(self) self._compile = CommandCompiler() self._completion_lexer = CompletionLexer(PythonLexer()) - self._hidden = False + self._hidden = True self._highlighter = FrontendHighlighter(self) self._kernel_manager = None @@ -127,6 +127,7 @@ class FrontendWidget(HistoryConsoleWidget): shown. Returns whether the source executed (i.e., returns True only if no more input is necessary). """ + # Use CommandCompiler to determine if more input is needed. try: code = self._compile(source, symbol='single') except (OverflowError, SyntaxError, ValueError): @@ -281,7 +282,7 @@ class FrontendWidget(HistoryConsoleWidget): elif status == 'aborted': text = "ERROR: ABORTED\n" self.appendPlainText(text) - self._hidden = False + self._hidden = True self._show_prompt('>>> ') self.executed.emit(rep) @@ -300,25 +301,3 @@ class FrontendWidget(HistoryConsoleWidget): doc = rep['content']['docstring'] if doc: self._call_tip_widget.show_tip(doc) - - -if __name__ == '__main__': - import sys - from IPython.frontend.qt.kernelmanager import QtKernelManager - - # Create KernelManager - xreq_addr = ('127.0.0.1', 5575) - sub_addr = ('127.0.0.1', 5576) - rep_addr = ('127.0.0.1', 5577) - kernel_manager = QtKernelManager(xreq_addr, sub_addr, rep_addr) - kernel_manager.sub_channel.start() - kernel_manager.xreq_channel.start() - - # Launch application - app = QtGui.QApplication(sys.argv) - widget = FrontendWidget(kernel_manager) - widget.setWindowTitle('Python') - widget.resize(640, 480) - widget.show() - sys.exit(app.exec_()) - diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py new file mode 100644 index 0000000..d72df3f --- /dev/null +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -0,0 +1,80 @@ +# Local imports. +from frontend_widget import FrontendWidget + + +class IPythonWidget(FrontendWidget): + """ A FrontendWidget for an IPython kernel. + """ + + #--------------------------------------------------------------------------- + # 'FrontendWidget' interface + #--------------------------------------------------------------------------- + + def __init__(self, kernel_manager, parent=None): + super(IPythonWidget, self).__init__(kernel_manager, parent) + + self._magic_overrides = {} + + def execute_source(self, source, hidden=False, interactive=False): + """ Reimplemented to override magic commands. + """ + magic_source = source.strip() + if magic_source.startswith('%'): + magic_source = magic_source[1:] + magic, sep, arguments = magic_source.partition(' ') + if not magic: + magic = magic_source + + callback = self._magic_overrides.get(magic) + if callback: + output = callback(arguments) + if output: + self.appendPlainText(output) + self._show_prompt('>>> ') + return True + else: + return super(IPythonWidget, self).execute_source(source, hidden, + interactive) + + #--------------------------------------------------------------------------- + # 'IPythonWidget' interface + #--------------------------------------------------------------------------- + + def set_magic_override(self, magic, callback): + """ Overrides an IPython magic command. This magic will be intercepted + by the frontend rather than passed on to the kernel and 'callback' + will be called with a single argument: a string of argument(s) for + the magic. The callback can (optionally) return text to print to the + console. + """ + self._magic_overrides[magic] = callback + + def remove_magic_override(self, magic): + """ Removes the override for the specified magic, if there is one. + """ + try: + del self._magic_overrides[magic] + except KeyError: + pass + + +if __name__ == '__main__': + import sys + from IPython.frontend.qt.kernelmanager import QtKernelManager + + # Create KernelManager + xreq_addr = ('127.0.0.1', 5575) + sub_addr = ('127.0.0.1', 5576) + rep_addr = ('127.0.0.1', 5577) + kernel_manager = QtKernelManager(xreq_addr, sub_addr, rep_addr) + kernel_manager.sub_channel.start() + kernel_manager.xreq_channel.start() + + # Launch application + app = QtGui.QApplication(sys.argv) + widget = IPythonWidget(kernel_manager) + widget.setWindowTitle('Python') + widget.resize(640, 480) + widget.show() + sys.exit(app.exec_()) + diff --git a/IPython/zmq/kernelmanager.py b/IPython/zmq/kernelmanager.py index eee8b2c..a0fee7b 100644 --- a/IPython/zmq/kernelmanager.py +++ b/IPython/zmq/kernelmanager.py @@ -118,7 +118,7 @@ class SubSocketChannel(ZmqSocketChannel): self._flushed = False self.ioloop.add_callback(self._flush) while not self._flushed: - time.sleep(0) + time.sleep(0.01) def _flush(self): """Called in this thread by the IOLoop to indicate that all events have