[IPython-dev] qt4 support?
Darren Dale
dd55 at cornell.edu
Thu Jun 29 15:30:04 EDT 2006
Hello,
I just committed a qt4agg backend for matplotlib. Would some kind ipython dev
have a look at the following patch to support the qt4agg backend in ipython's
pylab mode? It seems to be working here.
Thanks,
Darren
Index: IPython/Shell.py
===================================================================
--- IPython/Shell.py (revision 1383)
+++ IPython/Shell.py (working copy)
@@ -847,6 +847,81 @@
self.timer.start( self.TIMEOUT, True )
return result
+
+class IPShellQt4(threading.Thread):
+ """Run a Qt event loop in a separate thread.
+
+ Python commands can be passed to the thread where they will be executed.
+ This is implemented by periodically checking for passed code using a
+ Qt timer / slot."""
+
+ TIMEOUT = 100 # Millisecond interval between timeouts.
+
+ def __init__(self,argv=None,user_ns=None,user_global_ns=None,
+ debug=0,shell_class=MTInteractiveShell):
+
+ from PyQt4 import QtCore, QtGui
+
+ class newQApplication:
+ def __init__( self ):
+ self.QApplication = QtGui.QApplication
+
+ def __call__( *args, **kwargs ):
+ return QtGui.qApp
+
+ def exec_loop( *args, **kwargs ):
+ pass
+
+ def __getattr__( self, name ):
+ return getattr( self.QApplication, name )
+
+ QtGui.QApplication = newQApplication()
+
+ # Allows us to use both Tk and QT.
+ self.tk = get_tk()
+
+ self.IP = make_IPython(argv,user_ns=user_ns,
+ user_global_ns=user_global_ns,
+ debug=debug,
+ shell_class=shell_class,
+ on_kill=[QtGui.qApp.exit])
+
+ # HACK: slot for banner in self; it will be passed to the mainloop
+ # method only and .run() needs it. The actual value will be set by
+ # .mainloop().
+ self._banner = None
+
+ threading.Thread.__init__(self)
+
+ def run(self):
+ self.IP.mainloop(self._banner)
+ self.IP.kill()
+
+ def mainloop(self,sys_exit=0,banner=None):
+
+ from PyQt4 import QtCore, QtGui
+
+ self._banner = banner
+
+ if QtGui.QApplication.startingUp():
+ a = QtGui.QApplication.QApplication(sys.argv)
+ self.timer = QtCore.QTimer()
+ QtCore.QObject.connect( self.timer, QtCore.SIGNAL( 'timeout()' ),
self.on_timer )
+
+ self.start()
+ self.timer.start( self.TIMEOUT )
+ while True:
+ if self.IP._kill: break
+ QtGui.qApp.exec_()
+ self.join()
+
+ def on_timer(self):
+ update_tk(self.tk)
+ result = self.IP.runcode()
+ self.timer.start( self.TIMEOUT )
+ return result
+
+
# A set of matplotlib public IPython shell classes, for single-threaded
# (Tk* and FLTK* backends) and multithreaded (GTK* and WX* backends) use.
class IPShellMatplotlib(IPShell):
@@ -887,6 +962,15 @@
IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
shell_class=MatplotlibMTShell)
+class IPShellMatplotlibQt4(IPShellQt4):
+ """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
+
+ Multi-threaded class, meant for the Qt4* backends."""
+
+ def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
+ IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
+ shell_class=MatplotlibMTShell)
+
#-----------------------------------------------------------------------------
# Factory functions to actually start the proper thread-aware shell
@@ -907,6 +991,8 @@
sh_class = IPShellMatplotlibGTK
elif backend.startswith('WX'):
sh_class = IPShellMatplotlibWX
+ elif backend.startswith('Qt4'):
+ sh_class = IPShellMatplotlibQt4
elif backend.startswith('Qt'):
sh_class = IPShellMatplotlibQt
else:
@@ -935,6 +1021,8 @@
shell = IPShellGTK
elif arg1.endswith( '-qthread' ):
shell = IPShellQt
+ elif arg1.endswith( '-q4thread' ):
+ shell = IPShellQt4
elif arg1.endswith('-wthread'):
shell = IPShellWX
elif arg1.endswith('-pylab'):
Index: IPython/ipmaker.py
===================================================================
--- IPython/ipmaker.py (revision 1383)
+++ IPython/ipmaker.py (working copy)
@@ -170,7 +170,7 @@
# The "ignore" option is a kludge so that Emacs buffers don't crash,
since
# the 'C-c !' command in emacs automatically appends a -i option at the
end.
cmdline_only = ('help ignore|i ipythondir=s Version upgrade '
- 'gthread! qthread! wthread! pylab! tk!')
+ 'gthread! qthread! q4thread! wthread! pylab! tk!')
# Build the actual name list to be used by DPyGetOpt
opts_names = qw(cmdline_opts) + qw(cmdline_only)
@@ -221,6 +221,7 @@
system_verbose = 0,
gthread = 0,
qthread = 0,
+ q4thread = 0,
wthread = 0,
pylab = 0,
tk = 0,
--
Darren S. Dale, Ph.D.
Cornell High Energy Synchrotron Source
Cornell University
200L Wilson Lab
Rt. 366 & Pine Tree Road
Ithaca, NY 14853
dd55 at cornell.edu
office: (607) 255-9894
fax: (607) 255-9001
More information about the IPython-dev
mailing list