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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel