diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py
index cf427f3..1d8cff0 100644
--- a/IPython/frontend/qt/console/console_widget.py
+++ b/IPython/frontend/qt/console/console_widget.py
@@ -174,6 +174,8 @@ class ConsoleWidget(Configurable, QtGui.QWidget):
         self._filter_drag = False
         self._filter_resize = False
         self._html_exporter = HtmlExporter(self._control)
+        self._input_buffer_executing = ''
+        self._input_buffer_pending = ''
         self._kill_ring = QtKillRing(self._control)
         self._prompt = ''
         self._prompt_html = None
@@ -439,7 +441,7 @@ class ConsoleWidget(Configurable, QtGui.QWidget):
         else:
             if complete:
                 self._append_plain_text('\n')
-                self._executing_input_buffer = self.input_buffer
+                self._input_buffer_executing = self.input_buffer
                 self._executing = True
                 self._prompt_finished()
 
@@ -478,11 +480,14 @@ class ConsoleWidget(Configurable, QtGui.QWidget):
 
     def _get_input_buffer(self):
         """ The text that the user has entered entered at the current prompt.
+
+        If the console is currently executing, the text that is executing will
+        always be returned.
         """
         # If we're executing, the input buffer may not even exist anymore due to
         # the limit imposed by 'buffer_size'. Therefore, we store it.
         if self._executing:
-            return self._executing_input_buffer
+            return self._input_buffer_executing
 
         cursor = self._get_end_cursor()
         cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
@@ -492,11 +497,16 @@ class ConsoleWidget(Configurable, QtGui.QWidget):
         return input_buffer.replace('\n' + self._continuation_prompt, '\n')
 
     def _set_input_buffer(self, string):
-        """ Replaces the text in the input buffer with 'string'.
+        """ Sets the text in the input buffer.
+
+        If the console is currently executing, this call has no *immediate*
+        effect. When the execution is finished, the input buffer will be updated
+        appropriately.
         """
-        # For now, it is an error to modify the input buffer during execution.
+        # If we're executing, store the text for later.
         if self._executing:
-            raise RuntimeError("Cannot change input buffer during execution.")
+            self._input_buffer_pending = string
+            return
 
         # Remove old text.
         cursor = self._get_end_cursor()
@@ -1575,10 +1585,16 @@ class ConsoleWidget(Configurable, QtGui.QWidget):
         self._control.setReadOnly(False)
         self._control.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True)
 
-        self._control.moveCursor(QtGui.QTextCursor.End)
         self._executing = False
         self._prompt_started_hook()
 
+        # If the input buffer has changed while executing, load it.
+        if self._input_buffer_pending:
+            self.input_buffer = self._input_buffer_pending
+            self._input_buffer_pending = ''
+
+        self._control.moveCursor(QtGui.QTextCursor.End)
+
     def _readline(self, prompt='', callback=None):
         """ Reads one line of input from the user. 
 
diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py
index fd6521f..6fa8053 100644
--- a/IPython/frontend/qt/console/ipython_widget.py
+++ b/IPython/frontend/qt/console/ipython_widget.py
@@ -102,7 +102,6 @@ class IPythonWidget(FrontendWidget):
         super(IPythonWidget, self).__init__(*args, **kw)
 
         # IPythonWidget protected variables.
-        self._code_to_load = None
         self._payload_handlers = { 
             self._payload_source_edit : self._handle_payload_edit,
             self._payload_source_exit : self._handle_payload_exit,
@@ -322,11 +321,6 @@ class IPythonWidget(FrontendWidget):
         self._set_continuation_prompt(
             self._make_continuation_prompt(self._prompt), html=True)
 
-        # Load code from the %loadpy magic, if necessary.
-        if self._code_to_load is not None:
-            self.input_buffer = dedent(self._code_to_load.rstrip())
-            self._code_to_load = None
-
     def _show_interpreter_prompt_for_reply(self, msg):
         """ Reimplemented for IPython-style prompts.
         """
@@ -460,9 +454,7 @@ class IPythonWidget(FrontendWidget):
         self.exit_requested.emit()
 
     def _handle_payload_next_input(self, item):
-        # Simply store the text for now. It is written to the buffer when
-        # _show_interpreter_prompt is called.
-        self._code_to_load = item['text']
+        self.input_buffer = dedent(item['text'].rstrip())
 
     def _handle_payload_page(self, item):
         # Since the plain text widget supports only a very small subset of HTML