Hi all
   I ported the QtAgg backend over to Qt4 and created a patch for adding this 
backend to matplotlib with the name, Qt4Agg.  I include it here, for anyone 
interested.   I also noticed an earlier message like this, seemingly without 
resolution.   Is there other- maybe, better- code for Qt4 available 
somewhere?

Kevin Mueller
Dept. Atmospheric Science, Univ. Illinois Urbana-Qt4Champaign
diff -Naur matplotlib-0.87.3/lib/matplotlib/__init__.py matplotlib-0.87.3.old/lib/matplotlib/__init__.py
--- matplotlib-0.87.3/lib/matplotlib/__init__.py	2006-07-05 22:04:59.000000000 -0500
+++ matplotlib-0.87.3.old/lib/matplotlib/__init__.py	2006-07-05 22:02:14.000000000 -0500
@@ -467,8 +467,8 @@
 def validate_backend(s, fail_on_err = True):
     s=s.lower()
     backends = ['Agg2', 'Agg', 'Aqt', 'Cairo', 'CocoaAgg', 'EMF', 'GD', 'GDK', 'GTK',
-                'GTKAgg', 'GTKCairo', 'FltkAgg', 'Paint', 'Pdf', 'PS', 'QtAgg', 
-                'Qt4Agg', 'SVG', 'Template', 'TkAgg', 'WX', 'WXAgg', ]
+                'GTKAgg', 'GTKCairo', 'FltkAgg', 'Paint', 'Pdf', 'PS', 'QtAgg', 'SVG',
+                'Template', 'TkAgg', 'WX', 'WXAgg', ]
     for i in backends:
         if s == i.lower(): return i
     if fail_on_err: raise ValueError('Backend must be %s, or %s'% \
diff -Naur matplotlib-0.87.3/lib/matplotlib/backends/__init__.py matplotlib-0.87.3.old/lib/matplotlib/backends/__init__.py
--- matplotlib-0.87.3/lib/matplotlib/backends/__init__.py	2006-07-05 22:07:13.000000000 -0500
+++ matplotlib-0.87.3.old/lib/matplotlib/backends/__init__.py	2006-07-05 22:02:14.000000000 -0500
@@ -4,8 +4,8 @@
 __all__ = ['backend','show','draw_if_interactive',
            'new_figure_manager', 'backend_version']
 
-interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'FltkAgg', 'QtAgg', 'Qt4Agg',
-                  'TkAgg', 'WX', 'WXAgg', 'CocoaAgg', 'Aqt']
+interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'FltkAgg', 'QtAgg', 'TkAgg', 
+                  'WX', 'WXAgg', 'CocoaAgg', 'Aqt']
 non_interactive_bk = ['Agg2', 'Agg', 'Cairo', 'EMF', 'GD', 'GDK', 'Paint', 
 		      'Pdf', 'PS', 'SVG', 'Template']
 all_backends = interactive_bk + non_interactive_bk
diff -Naur matplotlib-0.87.3/lib/matplotlib/backends/backend_qt4.py matplotlib-0.87.3.old/lib/matplotlib/backends/backend_qt4.py
--- matplotlib-0.87.3/lib/matplotlib/backends/backend_qt4.py	2006-07-05 22:07:55.000000000 -0500
+++ matplotlib-0.87.3.old/lib/matplotlib/backends/backend_qt4.py	1969-12-31 18:00:00.000000000 -0600
@@ -1,340 +0,0 @@
-from __future__ import division
-import math
-import os
-import sys
-
-import matplotlib
-from matplotlib import verbose
-from matplotlib.numerix import asarray, fromstring, UInt8, zeros, \
-     where, transpose, nonzero, indices, ones, nx
-import matplotlib.numerix as numerix
-from matplotlib.cbook import is_string_like, enumerate, onetrue
-from matplotlib.font_manager import fontManager
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
-     FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.figure import Figure
-from matplotlib.mathtext import math_parse_s_ft2font
-
-from PyQt4 import QtCore, QtGui
-
-backend_version = "0.9.1"
-def fn_name(): return sys._getframe(1).f_code.co_name
-
-DEBUG = False
-
-cursord = {
-    cursors.MOVE          : QtCore.Qt.PointingHandCursor,
-    cursors.HAND          : QtCore.Qt.WaitCursor,
-    cursors.POINTER       : QtCore.Qt.ArrowCursor,
-    cursors.SELECT_REGION : QtCore.Qt.CrossCursor,
-    }
-
-def draw_if_interactive():
-    """
-    Is called after every pylab drawing command
-    """
-    if matplotlib.is_interactive():
-        figManager =  Gcf.get_active()
-        if figManager != None:
-            figManager.canvas.draw()
-
-def show( mainloop=True ):
-    """
-    Show all the figures and enter the qt main loop
-    This should be the last line of your script
-    """
-    for manager in Gcf.get_all_fig_managers():
-        manager.window.show()
-        
-    if DEBUG: print 'Inside show'
-    figManager =  Gcf.get_active()
-    if figManager != None:
-        figManager.canvas.draw()
-        #if ( createQApp ):
-        #   qtapplication.setMainWidget( figManager.canvas )
-
-    if mainloop and createQApp:
-        QtCore.QObject.connect( qtapplication, QtCore.SIGNAL( "lastWindowClosed()" ),
-                            qtapplication, QtCore.SLOT( "quit()" ) )
-        qtapplication.exec_()    
-
-
-def new_figure_manager( num, *args, **kwargs ):
-    """
-    Create a new figure manager instance
-    """
-    thisFig = Figure( *args, **kwargs )
-    canvas = FigureCanvasQT( thisFig )
-    manager = FigureManagerQT( canvas, num )
-    return manager
-
-
-class FigureCanvasQT( QtGui.QWidget, FigureCanvasBase ):
-    keyvald = { QtCore.Qt.Key_Control : 'control',
-                QtCore.Qt.Key_Shift : 'shift',
-                QtCore.Qt.Key_Alt : 'alt',
-               }
-    # left 1, middle 2, right 3
-    buttond = {1:1, 2:3, 4:2}
-    def __init__( self, figure ):
-        if DEBUG: print 'FigureCanvasQt: ', figure
-        FigureCanvasBase.__init__( self, figure )
-        QtGui.QWidget.__init__( self, None )
-        self.figure = figure
-        self.setMouseTracking( True )
-
-        w,h = self.get_width_height()
-        self.resize( w, h )
-        
-    def mousePressEvent( self, event ):
-        x = event.pos().x()
-        # flipy so y=0 is bottom of canvas
-        y = self.figure.bbox.height() - event.pos().y()
-        button = self.buttond[event.button()]
-        FigureCanvasBase.button_press_event( self, x, y, button )
-        if DEBUG: print 'button pressed:', event.button()
-        
-    def mouseMoveEvent( self, event ):
-        x = event.x()
-        # flipy so y=0 is bottom of canvas
-        y = self.figure.bbox.height() - event.y()
-        FigureCanvasBase.motion_notify_event( self, x, y )
-        if DEBUG: print 'mouse move'
-
-    def mouseReleaseEvent( self, event ):
-        x = event.x()
-        # flipy so y=0 is bottom of canvas
-        y = self.figure.bbox.height() - event.y()
-        button = self.buttond[event.button()]
-        FigureCanvasBase.button_release_event( self, x, y, button )
-        if DEBUG: print 'button released'
-        self.draw()
-
-    def keyPressEvent( self, event ):
-        key = self._get_key( event )
-        FigureCanvasBase.key_press_event( self, key )
-        if DEBUG: print 'key press', key
-
-    def keyReleaseEvent( self, event ):
-        key = self._get_key(event)
-        FigureCanvasBase.key_release_event( self, key )
-        if DEBUG: print 'key release', key
-
-    def resizeEvent( self, event ):
-        if DEBUG: print 'resize (%d x %d)' % (event.size().width(), event.size().height())
-        QtGui.QWidget.resizeEvent( self, event )
-
-    def resize( self, w, h ):
-        QtGui.QWidget.resize( self, w, h )
-
-    def _get_key( self, event ):
-        if event.key() < 256:
-            key = event.text().latin1()
-        elif self.keyvald.has_key( event.key() ):
-            key = self.keyvald[ event.key() ]
-        else:
-            key = None
-            
-        return key
-
-class FigureManagerQT( FigureManagerBase ):
-    """
-    Public attributes
-
-    canvas      : The FigureCanvas instance
-    num         : The Figure number
-    toolbar     : The QtGui.QToolBar
-    window      : The QtGui.QMainWindow 
-    """
-    
-    def __init__( self, canvas, num ):
-        if DEBUG: print 'FigureManagerQT.%s' % fn_name()
-        FigureManagerBase.__init__( self, canvas, num )
-        self.canvas = canvas
-        self.window = QtGui.QMainWindow()
-        self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
-
-        centralWidget = QtGui.QWidget( self.window )
-        self.canvas.setParent( centralWidget )
-        
-        # Give the keyboard focus to the figure instead of the manager
-        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
-        self.canvas.setFocus()
-        self.window.setWindowTitle( "Figure %d" % num )
-
-        QtCore.QObject.connect( self.window, QtCore.SIGNAL( 'destroyed()' ),
-                            self._widgetclosed )
-        self.window._destroying = False
-
-        if matplotlib.rcParams['toolbar'] == 'classic':
-            print "Classic toolbar is not yet supported"
-            #self.toolbar = NavigationToolbarQT( centralWidget, canvas )
-            self.toolbar = None
-        elif matplotlib.rcParams['toolbar'] == 'toolbar2':
-            self.toolbar = NavigationToolbar2QT( centralWidget, canvas )
-        else:
-            self.toolbar = None
-
-        # Use a vertical layout for the plot and the toolbar.  Set the
-        # stretch to all be in the plot so the toolbar doesn't resize.
-        layout = QtGui.QVBoxLayout( centralWidget )
-        layout.addWidget( self.canvas, 1 )
-        if self.toolbar:
-           layout.addWidget( self.toolbar, 0 )
-
-        self.window.setCentralWidget( centralWidget )
-
-        # Reset the window height so the canvas will be the right
-        # size.  This ALMOST works right.  The first issue is that the
-        # height w/ a toolbar seems to be off by just a little bit (so
-        # we add 4 pixels).  The second is that the total width/height
-        # is slightly smaller that we actually want.  It seems like
-        # the border of the window is being included in the size but
-        # AFAIK there is no way to get that size.  
-        w = self.canvas.width()
-        h = self.canvas.height()
-        if self.toolbar:
-           h += self.toolbar.height() + 4
-        self.window.resize( w, h )
-        
-        if matplotlib.is_interactive():
-            self.window.show()
-
-        def notify_axes_change( fig ):
-           # This will be called whenever the current axes is changed
-           if self.toolbar != None: self.toolbar.update()
-           self.canvas.figure.add_axobserver( notify_axes_change )
-
-    def _widgetclosed( self ):
-        if self.window._destroying: return
-        self.window._destroying = True
-        Gcf.destroy(self.num)
-
-    def destroy( self, *args ):
-        if self.window._destroying: return
-        self.window._destroying = True
-        if DEBUG: print "destroy figure manager"
-        self.window.close(True)
-
-class NavigationToolbar2QT( NavigationToolbar2, QtGui.QWidget ):
-    # list of toolitems to add to the toolbar, format is:
-    # text, tooltip_text, image_file, callback(str)
-    toolitems = (
-        ('Home', 'Reset original view', 'home.ppm', 'home'),
-        ('Back', 'Back to  previous view','back.ppm', 'back'),
-        ('Forward', 'Forward to next view','forward.ppm', 'forward'),
-        (None, None, None, None),        
-        ('Pan', 'Pan axes with left mouse, zoom with right', 'move.ppm', 'pan'),
-        ('Zoom', 'Zoom to rectangle','zoom_to_rect.ppm', 'zoom'),
-        (None, None, None, None),
-        ('Save', 'Save the figure','filesave.ppm', 'save_figure'),
-        )
-        
-    def __init__( self, parent, canvas ):
-        self.canvas = canvas
-        QtGui.QWidget.__init__( self, parent )
-
-        # Layout toolbar buttons horizontally.
-        self.layout = QtGui.QHBoxLayout( self )
-        self.layout.setMargin( 2 )
-        
-        NavigationToolbar2.__init__( self, canvas )
-        
-    def _init_toolbar( self ):
-        basedir = matplotlib.rcParams[ 'datapath' ]
-        
-        for text, tooltip_text, image_file, callback in self.toolitems:
-            if text == None:
-                self.layout.addSpacing( 8 )
-                continue
-            
-            fname = os.path.join( basedir, image_file )
-            image = QtGui.QPixmap()
-            image.load( fname )
-
-            button = QtGui.QToolButton()
-            button.setIcon(QtGui.QIcon( image ))
-            button.setToolTip( tooltip_text )
-
-            # The automatic layout doesn't look that good - it's too close
-            # to the images so add a margin around it.
-            margin = 4
-            button.setFixedSize( image.width()+margin, image.height()+margin )
-
-            QtCore.QObject.connect( button, QtCore.SIGNAL( 'clicked()' ),
-                                getattr( self, callback ) )
-            self.layout.addWidget( button )
-
-        # Add the x,y location widget at the right side of the toolbar
-        # The stretch factor is 1 which means any resizing of the toolbar
-        # will resize this label instead of the buttons.
-        self.locLabel = QtGui.QLabel( "", self )
-        self.locLabel.setAlignment( QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter )
-        self.layout.addWidget( self.locLabel, 1 )
-
-    def dynamic_update( self ):
-        self.canvas.draw()
-
-    def set_message( self, s ):
-        self.locLabel.setText( s )
-
-    def set_cursor( self, cursor ):
-        if DEBUG: print 'Set cursor' , cursor
-        QtGui.QApplication.restoreOverrideCursor()
-        QtGui.QApplication.setOverrideCursor( QtGui.QCursor( cursord[cursor] ) )
-                
-    def draw_rubberband( self, event, x0, y0, x1, y1 ):
-        height = self.canvas.figure.bbox.height()
-        y1 = height - y1
-        y0 = height - y0
-        
-        w = abs(x1 - x0)
-        h = abs(y1 - y0)
-
-        rect = [ int(val)for val in min(x0,x1), min(y0, y1), w, h ]
-        self.canvas.drawRectangle( rect )
-    
-    def save_figure( self ):     
-        fname = QtGui.QFileDialog.getSaveFileName()
-        if fname:
-            self.canvas.print_figure( str(fname) )
-
-# set icon used when windows are minimized
-try:
-    QtGui.window_set_default_icon_from_file (
-        os.path.join( matplotlib.rcParams['datapath'], 'matplotlib.svg' ) )
-except:
-    verbose.report( 'Could not load matplotlib icon: %s' % sys.exc_info()[1] )
-
-
-def error_msg_qt( msg, parent=None ):
-    if not is_string_like( msg ):
-        msg = ','.join( map( str,msg ) )
-                         
-    QtGui.QMessageBox.warning( None, "Matplotlib", msg, QtGui.QMessageBox.Ok )
-
-def exception_handler( type, value, tb ):
-    """Handle uncaught exceptions
-    It does not catch SystemExit
-    """
-    msg = ''
-    # get the filename attribute if available (for IOError)
-    if hasattr(value, 'filename') and value.filename != None:
-        msg = value.filename + ': '
-    if hasattr(value, 'strerror') and value.strerror != None:
-        msg += value.strerror
-    else:
-        msg += str(value)
-
-    if len( msg ) : error_msg_qt( msg )
-
-
-FigureManager = FigureManagerQT
-
-# We need one and only one QApplication before we can build any Qt widgets
-# Detect if a QApplication exists.
-createQApp = QtGui.QApplication.startingUp()
-if createQApp:
-    if DEBUG: print "Starting up QApplication"
-    qtapplication = QtGui.QApplication( [" "] )
diff -Naur matplotlib-0.87.3/lib/matplotlib/backends/backend_qt4agg.py matplotlib-0.87.3.old/lib/matplotlib/backends/backend_qt4agg.py
--- matplotlib-0.87.3/lib/matplotlib/backends/backend_qt4agg.py	2006-07-05 22:08:01.000000000 -0500
+++ matplotlib-0.87.3.old/lib/matplotlib/backends/backend_qt4agg.py	1969-12-31 18:00:00.000000000 -0600
@@ -1,127 +0,0 @@
-"""
-Render to qt4 from agg
-"""
-from __future__ import division
-
-import os, sys
-from matplotlib import verbose
-from matplotlib.cbook import enumerate
-from matplotlib.figure import Figure
-
-from backend_agg import FigureCanvasAgg
-from backend_qt4 import FigureManagerQT, FigureCanvasQT,\
-     show, draw_if_interactive, backend_version
-import struct
-
-from PyQt4 import QtCore, QtGui
-
-DEBUG = False
-isLittleEndian = struct.pack('@i',7)=='\x07\x00\x00\x00'
-
-def new_figure_manager( num, *args, **kwargs ):
-    """
-    Create a new figure manager instance
-    """
-    if DEBUG: print 'backend_qt4agg.new_figure_manager'
-    thisFig = Figure( *args, **kwargs )
-    canvas = FigureCanvasQTAgg( thisFig )
-    return FigureManagerQT( canvas, num )
-
-class FigureCanvasQTAgg( FigureCanvasQT, FigureCanvasAgg ):
-    """
-    The canvas the figure renders into.  Calls the draw and print fig
-    methods, creates the renderers, etc...
-
-    Public attribute
-
-      figure - A Figure instance
-   """
-
-    def __init__( self, figure ):
-        if DEBUG: print 'FigureCanvasQtAgg: ', figure
-        FigureCanvasQT.__init__( self, figure )
-        FigureCanvasAgg.__init__( self, figure )
-        self.drawRect = False
-        self.rect = []
-        self.replot = True
-        self.pixmap = QtGui.QPixmap()
-     
-    def resizeEvent( self, e ):
-        FigureCanvasQT.resizeEvent( self, e )
-        w = e.size().width()
-        h = e.size().height()
-        if DEBUG: print "FigureCanvasQtAgg.resizeEvent(", w, ",", h, ")"
-        dpival = self.figure.dpi.get()
-        winch = w/dpival
-        hinch = h/dpival
-        self.figure.set_figsize_inches( winch, hinch )
-        self.draw()
-        
-    def drawRectangle( self, rect ):
-        self.rect = rect
-        self.drawRect = True
-        # False in repaint does not clear the image before repainting
-        self.repaint()
-
-    def paintEvent( self, e ):
-        """
-        Draw to the Agg backend and then copy the image to the QtGui.drawable.
-        In Qt, all drawing should be done inside of here when a widget is
-        shown onscreen.
-        """
-        
-        FigureCanvasQT.paintEvent( self, e )
-        if DEBUG: print 'FigureCanvasQtAgg.paintEvent: ', \
-           self.get_width_height()
-
-        p = QtGui.QPainter( self )
-        FigureCanvasAgg.draw( self )
-
-        # only replot data when needed
-        if ( self.replot ):
-            stringBuffer = str( self.buffer_rgba(0,0) )
-            
-
-            # matplotlib is in rgba byte order.
-            # qImage wants to put the bytes into argb format and
-            # is in a 4 byte unsigned int.  little endian system is LSB first
-            # and expects the bytes in reverse order (bgra).
-            # TODO: fix this to choose correct endian
-            if isLittleEndian:
-                stringBuffer = self.renderer._renderer.tostring_bgra()
-            else:
-                stringBuffer = self.renderer._renderer.tostring_argb()
-               
-            qImage = QtGui.QImage( stringBuffer, self.renderer.width,
-                                self.renderer.height, QtGui.QImage.Format_ARGB32)
-                
-            self.pixmap = QtGui.QPixmap.fromImage( qImage )
-    
-        p.drawPixmap( 0, 0, self.pixmap )
-
-        # draw the zoom rectangle to the QPainter
-        if ( self.drawRect ):
-            p.setPen( QtGui.QPen( QtCore.Qt.black, 1, QtCore.Qt.DotLine ) )
-            p.drawRect( self.rect[0], self.rect[1], self.rect[2], self.rect[3] )
-           
-        p.end()
-        self.replot = False
-        self.drawRect = False
-
-    def draw( self ):
-        """
-        Draw the figure when xwindows is ready for the update
-        """
-        
-        if DEBUG: print "FigureCanvasQtAgg.draw"
-        self.replot = True
-        self.repaint()
-        self.update()
-
-    def print_figure( self, filename, dpi=150, facecolor='w', edgecolor='w',
-                      orientation='portrait' ):
-        if DEBUG: print 'FigureCanvasQTAgg.print_figure'
-        agg = self.switch_backends( FigureCanvasAgg )
-        agg.print_figure( filename, dpi, facecolor, edgecolor, orientation )
-
-        
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to