diff --git a/IPython/frontend/qt/console/scripts/ipythonqt.py b/IPython/frontend/qt/console/scripts/ipythonqt.py
index f4409aa..ac892a0 100755
--- a/IPython/frontend/qt/console/scripts/ipythonqt.py
+++ b/IPython/frontend/qt/console/scripts/ipythonqt.py
@@ -35,8 +35,11 @@ def main():
     group = parser.add_mutually_exclusive_group()
     group.add_argument('--pure', action='store_true', help = \
                        'use a pure Python kernel instead of an IPython kernel')
-    group.add_argument('--pylab', action='store_true',
-                        help='use a kernel with PyLab enabled')
+    group.add_argument('--pylab', type=str, metavar='GUI', nargs='?', 
+                       const='auto', help = \
+                       "Pre-load matplotlib and numpy for interactive use. If GUI is not \
+                       given, the GUI backend is matplotlib's, otherwise use one of: \
+                       ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
     parser.add_argument('--rich', action='store_true',
                         help='use a rich text frontend')
     args = parser.parse_args()
@@ -56,7 +59,10 @@ def main():
             if args.rich:
                 kernel_manager.start_kernel(pylab='payload-svg')
             else:
-                kernel_manager.start_kernel(pylab='qt4')
+                if args.pylab == 'auto':
+                    kernel_manager.start_kernel(pylab='qt4')
+                else:
+                    kernel_manager.start_kernel(pylab=args.pylab)
         else:
             kernel_manager.start_kernel()
     kernel_manager.start_channels()
diff --git a/IPython/lib/pylabtools.py b/IPython/lib/pylabtools.py
index ad8ed7d..297c60a 100644
--- a/IPython/lib/pylabtools.py
+++ b/IPython/lib/pylabtools.py
@@ -73,8 +73,20 @@ def activate_matplotlib(backend):
     else:
         matplotlib.use(backend)
     matplotlib.interactive(True)
+
+    # This must be imported last in the matplotlib series, after
+    # backend/interactivity choices have been made
     import matplotlib.pylab as pylab
 
+    # XXX For now leave this commented out, but depending on discussions with
+    # mpl-dev, we may be able to allow interactive switching...
+    #import matplotlib.pyplot
+    #matplotlib.pyplot.switch_backend(backend)
+
+    pylab.show._needmain = False
+    # We need to detect at runtime whether show() is called by the user.
+    # For this, we wrap it into a decorator which adds a 'called' flag.
+    pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
 
 def import_pylab(user_ns, import_all=True):
     """Import the standard pylab symbols into user_ns."""
@@ -115,24 +127,8 @@ def pylab_activate(user_ns, gui=None, import_all=True):
     The actual gui used (if not given as input, it was obtained from matplotlib
     itself, and will be needed next to configure IPython's gui integration.
     """
-
     gui, backend = find_gui_and_backend(gui)
     activate_matplotlib(backend)
-
-    # This must be imported last in the matplotlib series, after
-    # backend/interactivity choices have been made
-    import matplotlib.pylab as pylab
-
-    # XXX For now leave this commented out, but depending on discussions with
-    # mpl-dev, we may be able to allow interactive switching...
-    #import matplotlib.pyplot
-    #matplotlib.pyplot.switch_backend(backend)
-
-    pylab.show._needmain = False
-    # We need to detect at runtime whether show() is called by the user.
-    # For this, we wrap it into a decorator which adds a 'called' flag.
-    pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
-
     import_pylab(user_ns)
 
     print """
diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py
index 6be1be3..3f7d5d2 100755
--- a/IPython/zmq/ipkernel.py
+++ b/IPython/zmq/ipkernel.py
@@ -293,16 +293,79 @@ class Kernel(Configurable):
 
 
 class QtKernel(Kernel):
+    """A Kernel subclass with Qt support."""
 
     def start(self):
         """Start a kernel with QtPy4 event loop integration."""
+
         from PyQt4 import QtGui, QtCore
-        self.qapp = app = QtGui.QApplication([])
-        self.qtimer = QtCore.QTimer()
-        self.qtimer.timeout.connect(self.do_one_iteration)
-        self.qtimer.start(50)
-        self.qapp.exec_()
+        self.app = QtGui.QApplication([])
+        self.app.setQuitOnLastWindowClosed (False)
+        self.timer = QtCore.QTimer()
+        self.timer.timeout.connect(self.do_one_iteration)
+        self.timer.start(50)
+        self.app.exec_()
+
+
+class WxKernel(Kernel):
+    """A Kernel subclass with Wx support."""
 
+    def start(self):
+        """Start a kernel with wx event loop support."""
+
+        import wx
+        doi = self.do_one_iteration
+
+        # We have to put the wx.Timer in a wx.Frame for it to fire properly.
+        # We make the Frame hidden when we create it in the main app below.
+        class TimerFrame(wx.Frame):
+            def __init__(self, func):
+                wx.Frame.__init__(self, None, -1)
+                self.timer = wx.Timer(self)
+                self.timer.Start(50)
+                self.Bind(wx.EVT_TIMER, self.on_timer)
+                self.func = func
+            def on_timer(self, event):
+                self.func()
+
+        # We need a custom wx.App to create our Frame subclass that has the
+        # wx.Timer to drive the ZMQ event loop.
+        class IPWxApp(wx.App):
+            def OnInit(self):
+                self.frame = TimerFrame(doi)
+                self.frame.Show(False)
+                return True
+
+        # The redirect=False here makes sure that wx doesn't replace
+        # sys.stdout/stderr with its own classes.
+        self.app = IPWxApp(redirect=False)
+        self.app.MainLoop()
+
+
+class TkKernel(Kernel):
+    """A Kernel subclass with Tk support."""
+
+    def start(self):
+        """Start a Tk enabled event loop."""
+
+        import Tkinter
+        doi = self.do_one_iteration
+
+        # For Tkinter, we create a Tk object and call its withdraw method.
+        class Timer(object):
+            def __init__(self, func):
+                self.app = Tkinter.Tk()
+                self.app.withdraw()
+                self.func = func
+            def on_timer(self):
+                self.func()
+                self.app.after(50, self.on_timer)
+            def start(self):
+                self.on_timer()  # Call it once to get things going.
+                self.app.mainloop()
+
+        self.timer = Timer(doi)
+        self.timer.start()
 
 #-----------------------------------------------------------------------------
 # Kernel main and launch functions
@@ -365,22 +428,21 @@ given, the GUI backend is matplotlib's, otherwise use one of: \
     _kernel_classes = {
         'qt' : QtKernel,
         'qt4' : QtKernel,
-        'payload-svg':Kernel
+        'payload-svg':Kernel,
+        'wx' : WxKernel,
+        'tk' : TkKernel
     }
     if namespace.pylab:
         if namespace.pylab == 'auto':
             gui, backend = pylabtools.find_gui_and_backend()
         else:
             gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
-        print gui, backend
         kernel_class = _kernel_classes.get(gui)
         if kernel_class is None:
             raise ValueError('GUI is not supported: %r' % gui)
         pylabtools.activate_matplotlib(backend)
 
-    print>>sys.__stdout__, kernel_class
     kernel = make_kernel(namespace, kernel_class, OutStream)
-    print >>sys.__stdout__, kernel
 
     if namespace.pylab:
         pylabtools.import_pylab(kernel.shell.user_ns)