From e30248bdf36993876c8b68fa3b9f264cffa45cc8 Mon Sep 17 00:00:00 2001 From: Joseph Mirabel Date: Wed, 15 May 2019 10:39:03 +0200 Subject: [PATCH] Revert "Add backends for matplotlib (version on MeVisLab)" This reverts commit 593d66939447007e675478a4bed77254743cf0f0. --- CMakeLists.txt | 1 - matplotlib/CMakeLists.txt | 2 - matplotlib/backends/backend_qt.py | 493 ------------ matplotlib/backends/backend_qt4.py | 716 ------------------ matplotlib/backends/backend_qt4agg.py | 142 ---- matplotlib/backends/backend_qtagg.py | 157 ---- matplotlib/backends/qt4_compat.py | 114 --- matplotlib/backends/qt4_editor/__init__.py | 7 - .../backends/qt4_editor/figureoptions.py | 142 ---- matplotlib/backends/qt4_editor/formlayout.py | 569 -------------- 10 files changed, 2343 deletions(-) delete mode 100644 matplotlib/CMakeLists.txt delete mode 100644 matplotlib/backends/backend_qt.py delete mode 100644 matplotlib/backends/backend_qt4.py delete mode 100644 matplotlib/backends/backend_qt4agg.py delete mode 100644 matplotlib/backends/backend_qtagg.py delete mode 100644 matplotlib/backends/qt4_compat.py delete mode 100644 matplotlib/backends/qt4_editor/__init__.py delete mode 100644 matplotlib/backends/qt4_editor/figureoptions.py delete mode 100644 matplotlib/backends/qt4_editor/formlayout.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ffb5c4f..322d4efa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,4 +377,3 @@ if(BUILD_TESTING) ) endif() -ADD_SUBDIRECTORY(matplotlib) diff --git a/matplotlib/CMakeLists.txt b/matplotlib/CMakeLists.txt deleted file mode 100644 index e3b8a24a..00000000 --- a/matplotlib/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -INSTALL(DIRECTORY backends - DESTINATION ${PythonQt_INSTALL_LIBRARY_DIR}/python2.7/site-packages/pythonqt/matplotlib) diff --git a/matplotlib/backends/backend_qt.py b/matplotlib/backends/backend_qt.py deleted file mode 100644 index da83199b..00000000 --- a/matplotlib/backends/backend_qt.py +++ /dev/null @@ -1,493 +0,0 @@ -from __future__ import division -import math -import os -import sys - -import matplotlib -from matplotlib import verbose -from matplotlib.cbook import is_string_like, onetrue -from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ - FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors -from matplotlib.backend_bases import ShowBase - -from matplotlib._pylab_helpers import Gcf -from matplotlib.figure import Figure -from matplotlib.mathtext import MathTextParser -from matplotlib.widgets import SubplotTool - -try: - import qt -except ImportError: - raise ImportError("Qt backend requires pyqt to be installed.") - -backend_version = "0.9.1" -def fn_name(): return sys._getframe(1).f_code.co_name - -DEBUG = False - -cursord = { - cursors.MOVE : qt.Qt.PointingHandCursor, - cursors.HAND : qt.Qt.WaitCursor, - cursors.POINTER : qt.Qt.ArrowCursor, - cursors.SELECT_REGION : qt.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 _create_qApp(): - """ - Only one qApp can exist at a time, so check before creating one - """ - if qt.QApplication.startingUp(): - if DEBUG: print "Starting up QApplication" - global qApp - qApp = qt.QApplication( [" "] ) - qt.QObject.connect( qApp, qt.SIGNAL( "lastWindowClosed()" ), - qApp, qt.SLOT( "quit()" ) ) - #remember that matplotlib created the qApp - will be used by show() - _create_qApp.qAppCreatedHere = True - -_create_qApp.qAppCreatedHere = False - -class Show(ShowBase): - def mainloop(self): - if _create_qApp.qAppCreatedHere: - qt.qApp.exec_loop() - -show = Show() - - -def new_figure_manager( num, *args, **kwargs ): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQT( thisFig ) - manager = FigureManagerQT( canvas, num ) - return manager - - -class FigureCanvasQT( qt.QWidget, FigureCanvasBase ): - keyvald = { qt.Qt.Key_Control : 'control', - qt.Qt.Key_Shift : 'shift', - qt.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 - _create_qApp() - - qt.QWidget.__init__( self, None, "QWidget figure" ) - FigureCanvasBase.__init__( self, figure ) - self.figure = figure - self.setMouseTracking( True ) - - w,h = self.get_width_height() - self.resize( w, h ) - - def enterEvent(self, event): - FigureCanvasBase.enter_notify_event(self, event) - - def leaveEvent(self, event): - FigureCanvasBase.leave_notify_event(self, event) - - 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' - - 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()) - qt.QWidget.resizeEvent( self, event ) - w = event.size().width() - h = event.size().height() - if DEBUG: print "FigureCanvasQt.resizeEvent(", w, ",", h, ")" - dpival = self.figure.dpi - winch = w/dpival - hinch = h/dpival - self.figure.set_size_inches( winch, hinch ) - self.draw() - - def resize( self, w, h ): - # Pass through to Qt to resize the widget. - qt.QWidget.resize( self, w, h ) - - # Resize the figure by converting pixels to inches. - pixelPerInch = self.figure.dpi - wInch = w / pixelPerInch - hInch = h / pixelPerInch - self.figure.set_size_inches( wInch, hInch ) - - # Redraw everything. - self.draw() - - def sizeHint( self ): - w, h = self.get_width_height() - return qt.QSize( w, h ) - - def minumumSizeHint( self ): - return qt.QSize( 10, 10 ) - - def _get_key( self, event ): - if event.key() < 256: - key = event.text().latin1() - elif event.key() in self.keyvald: - key = self.keyvald[ event.key() ] - else: - key = None - - return key - - def flush_events(self): - qt.qApp.processEvents() - - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - -class FigureManagerQT( FigureManagerBase ): - """ - Public attributes - - canvas : The FigureCanvas instance - num : The Figure number - toolbar : The qt.QToolBar - window : The qt.QMainWindow - """ - - def __init__( self, canvas, num ): - if DEBUG: print 'FigureManagerQT.%s' % fn_name() - FigureManagerBase.__init__( self, canvas, num ) - self.canvas = canvas - self.window = qt.QMainWindow( None, None, qt.Qt.WDestructiveClose ) - self.window.closeEvent = self._widgetCloseEvent - - centralWidget = qt.QWidget( self.window ) - self.canvas.reparent( centralWidget, qt.QPoint( 0, 0 ) ) - - # Give the keyboard focus to the figure instead of the manager - self.canvas.setFocusPolicy( qt.QWidget.ClickFocus ) - self.canvas.setFocus() - self.window.setCaption( "Figure %d" % num ) - - self.window._destroying = False - - self.toolbar = self._get_toolbar(self.canvas, centralWidget) - - # 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. - self.layout = qt.QVBoxLayout( centralWidget ) - self.layout.addWidget( self.canvas, 1 ) - - if self.toolbar: - self.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() - - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: 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 _widgetCloseEvent( self, event ): - self._widgetclosed() - qt.QWidget.closeEvent( self.window, event ) - - def _get_toolbar(self, canvas, parent): - # must be inited after the window, drawingArea and figure - # attrs are set - if matplotlib.rcParams['toolbar'] == 'classic': - print "Classic toolbar is not yet supported" - elif matplotlib.rcParams['toolbar'] == 'toolbar2': - toolbar = NavigationToolbar2QT(canvas, parent) - else: - toolbar = None - return toolbar - - def resize(self, width, height): - 'set the canvas size in pixels' - self.window.resize(width, height) - - def show(self): - self.window.show() - - def destroy( self, *args ): - if self.window._destroying: return - self.window._destroying = True - if self.toolbar: self.toolbar.destroy() - if DEBUG: print "destroy figure manager" - self.window.close(True) - - def set_window_title(self, title): - self.window.setCaption(title) - -class NavigationToolbar2QT( NavigationToolbar2, qt.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), - ('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'), - ('Save', 'Save the figure','filesave.ppm', 'save_figure'), - ) - - def __init__( self, canvas, parent ): - self.canvas = canvas - self.buttons = {} - - qt.QWidget.__init__( self, parent ) - - # Layout toolbar buttons horizontally. - self.layout = qt.QHBoxLayout( self ) - self.layout.setMargin( 2 ) - - NavigationToolbar2.__init__( self, canvas ) - - def _init_toolbar( self ): - basedir = os.path.join(matplotlib.rcParams[ 'datapath' ],'images') - - 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 = qt.QPixmap() - image.load( fname ) - - button = qt.QPushButton( qt.QIconSet( image ), "", self ) - qt.QToolTip.add( button, tooltip_text ) - - self.buttons[ text ] = button - - # 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 ) - - qt.QObject.connect( button, qt.SIGNAL( 'clicked()' ), - getattr( self, callback ) ) - self.layout.addWidget( button ) - - self.buttons[ 'Pan' ].setToggleButton( True ) - self.buttons[ 'Zoom' ].setToggleButton( True ) - - # 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 = qt.QLabel( "", self ) - self.locLabel.setAlignment( qt.Qt.AlignRight | qt.Qt.AlignVCenter ) - self.locLabel.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Ignored, - qt.QSizePolicy.Ignored)) - self.layout.addWidget( self.locLabel, 1 ) - - # reference holder for subplots_adjust window - self.adj_window = None - - - def destroy( self ): - for text, tooltip_text, image_file, callback in self.toolitems: - if text is not None: - qt.QObject.disconnect( self.buttons[ text ], - qt.SIGNAL( 'clicked()' ), - getattr( self, callback ) ) - - def pan( self, *args ): - self.buttons[ 'Zoom' ].setOn( False ) - NavigationToolbar2.pan( self, *args ) - - def zoom( self, *args ): - self.buttons[ 'Pan' ].setOn( False ) - NavigationToolbar2.zoom( self, *args ) - - 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 - qt.QApplication.restoreOverrideCursor() - qt.QApplication.setOverrideCursor( qt.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 configure_subplots(self): - self.adj_window = qt.QMainWindow(None, None, qt.Qt.WDestructiveClose) - win = self.adj_window - win.setCaption("Subplot Configuration Tool") - - toolfig = Figure(figsize=(6,3)) - toolfig.subplots_adjust(top=0.9) - w = int (toolfig.bbox.width) - h = int (toolfig.bbox.height) - - canvas = self._get_canvas(toolfig) - tool = SubplotTool(self.canvas.figure, toolfig) - centralWidget = qt.QWidget(win) - canvas.reparent(centralWidget, qt.QPoint(0, 0)) - win.setCentralWidget(centralWidget) - - layout = qt.QVBoxLayout(centralWidget) - layout.addWidget(canvas, 1) - - win.resize(w, h) - canvas.setFocus() - win.show() - - def _get_canvas(self, fig): - return FigureCanvasQT(fig) - - def save_figure(self, *args): - filetypes = self.canvas.get_supported_filetypes_grouped() - sorted_filetypes = filetypes.items() - sorted_filetypes.sort() - default_filetype = self.canvas.get_default_filetype() - - start = "image." + default_filetype - filters = [] - selectedFilter = None - for name, exts in sorted_filetypes: - exts_list = " ".join(['*.%s' % ext for ext in exts]) - filter = '%s (%s)' % (name, exts_list) - if default_filetype in exts: - selectedFilter = filter - filters.append(filter) - filters = ';;'.join(filters) - - fname = qt.QFileDialog.getSaveFileName( - start, filters, self, "Save image", "Choose a filename to save to", - selectedFilter) - if fname: - try: - self.canvas.print_figure( unicode(fname) ) - except Exception, e: - qt.QMessageBox.critical( - self, "Error saving file", str(e), - qt.QMessageBox.Ok, qt.QMessageBox.NoButton) - - def set_history_buttons( self ): - canBackward = ( self._views._pos > 0 ) - canForward = ( self._views._pos < len( self._views._elements ) - 1 ) - self.buttons[ 'Back' ].setEnabled( canBackward ) - self.buttons[ 'Forward' ].setEnabled( canForward ) - -# set icon used when windows are minimized -try: - # TODO: This is badly broken - qt.window_set_default_icon_from_file ( - os.path.join( matplotlib.rcParams['datapath'], 'images', '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 ) ) - - qt.QMessageBox.warning( None, "Matplotlib", msg, qt.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 - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: CT5bte7ub8d4LS/3a2EDvMyHn0puJoWF7sNxqUzg8+DKjnT/vetHbZ7MBrsASrOwqOQ3p1XoL36DDrGOznyISA== -#//# MeVis end diff --git a/matplotlib/backends/backend_qt4.py b/matplotlib/backends/backend_qt4.py deleted file mode 100644 index 65071908..00000000 --- a/matplotlib/backends/backend_qt4.py +++ /dev/null @@ -1,716 +0,0 @@ -from __future__ import division -import math -import os -import sys - -import matplotlib -from matplotlib import verbose -from matplotlib.cbook import is_string_like, onetrue -from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ - FigureManagerBase, FigureCanvasBase, NavigationToolbar2, IdleEvent, \ - cursors, TimerBase -from matplotlib.backend_bases import ShowBase - -from matplotlib._pylab_helpers import Gcf -from matplotlib.figure import Figure -from matplotlib.mathtext import MathTextParser -from matplotlib.widgets import SubplotTool -#try: -# import matplotlib.backends.qt4_editor.figureoptions as figureoptions -#except ImportError: -# TODO MEVIS: disabled figureoptions since they require some rework to make them work with PythonQt -figureoptions = None - -from qt4_compat import QtCore, QtGui, _getSaveFileName, __version__ - -backend_version = __version__ -def fn_name(): return sys._getframe(1).f_code.co_name - -DEBUG = False - -cursord = { - cursors.MOVE : QtCore.Qt.SizeAllCursor, - cursors.HAND : QtCore.Qt.PointingHandCursor, - 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_idle() - -def _create_qApp(): - """ - Only one qApp can exist at a time, so check before creating one. - """ - return - # Disabled for MeVisLab, since QApplication is already there - if QtGui.QApplication.startingUp(): - if DEBUG: print "Starting up QApplication" - global qApp - app = QtGui.QApplication.instance() - if app is None: - qApp = QtGui.QApplication( [" "] ) - QtCore.QObject.connect( qApp, QtCore.SIGNAL( "lastWindowClosed()" ), - qApp, QtCore.SLOT( "quit()" ) ) - else: - qApp = app - -class Show(ShowBase): - def mainloop(self): - pass - #QtGui.qApp.exec_() - -show = Show() - - -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 TimerQT(TimerBase): - ''' - Subclass of :class:`backend_bases.TimerBase` that uses Qt4 timer events. - - Attributes: - * interval: The time between timer events in milliseconds. Default - is 1000 ms. - * single_shot: Boolean flag indicating whether this timer should - operate as single shot (run once and then stop). Defaults to False. - * callbacks: Stores list of (func, args) tuples that will be called - upon timer events. This list can be manipulated directly, or the - functions add_callback and remove_callback can be used. - ''' - def __init__(self, *args, **kwargs): - TimerBase.__init__(self, *args, **kwargs) - - # Create a new timer and connect the timeout() signal to the - # _on_timer method. - self._timer = QtCore.QTimer() - QtCore.QObject.connect(self._timer, QtCore.SIGNAL('timeout()'), - self._on_timer) - - def __del__(self): - # Probably not necessary in practice, but is good behavior to disconnect - TimerBase.__del__(self) - QtCore.QObject.disconnect(self._timer , QtCore.SIGNAL('timeout()'), - self._on_timer) - - def _timer_set_single_shot(self): - self._timer.setSingleShot(self._single) - - def _timer_set_interval(self): - self._timer.setInterval(self._interval) - - def _timer_start(self): - self._timer.start() - - def _timer_stop(self): - self._timer.stop() - - -class FigureCanvasQT( QtGui.QWidget, FigureCanvasBase ): - keyvald = { QtCore.Qt.Key_Control : 'control', - QtCore.Qt.Key_Shift : 'shift', - QtCore.Qt.Key_Alt : 'alt', - QtCore.Qt.Key_Return : 'enter' - } - # left 1, middle 2, right 3 - buttond = {1:1, 2:3, 4:2} - def __init__( self, figure ): - if DEBUG: print 'FigureCanvasQt: ', figure - _create_qApp() - - QtGui.QWidget.__init__( self ) - FigureCanvasBase.__init__( self, figure ) - self.figure = figure - self.setMouseTracking( True ) - self._idle = True - # hide until we can test and fix - #self.startTimer(backend_IdleEvent.milliseconds) - w,h = self.get_width_height() - self.resize( w, h ) - - QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'), - self.close_event) - - def __timerEvent(self, event): - # hide until we can test and fix - self.mpl_idle_event(event) - - def enterEvent(self, event): - FigureCanvasBase.enter_notify_event(self, event) - - def leaveEvent(self, event): - QtGui.QApplication.restoreOverrideCursor() - FigureCanvasBase.leave_notify_event(self, event) - - 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' - - def wheelEvent( self, event ): - x = event.x() - # flipy so y=0 is bottom of canvas - y = self.figure.bbox.height - event.y() - # from QWheelEvent::delta doc - steps = event.delta()/120 - if (event.orientation() == QtCore.Qt.Vertical): - FigureCanvasBase.scroll_event( self, x, y, steps) - if DEBUG: print 'scroll event : delta = %i, steps = %i ' % (event.delta(),steps) - - def keyPressEvent( self, event ): - key = self._get_key( event ) - if key is None: - return - FigureCanvasBase.key_press_event( self, key ) - if DEBUG: print 'key press', key - - def keyReleaseEvent( self, event ): - key = self._get_key(event) - if key is None: - return - 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()) - w = event.size().width() - h = event.size().height() - if DEBUG: print "FigureCanvasQtAgg.resizeEvent(", w, ",", h, ")" - dpival = self.figure.dpi - winch = w/dpival - hinch = h/dpival - self.figure.set_size_inches( winch, hinch ) - self.draw() - self.update() - QtGui.QWidget.resizeEvent(self, event) - - def sizeHint( self ): - w, h = self.get_width_height() - return QtCore.QSize( w, h ) - - def minumumSizeHint( self ): - return QtCore.QSize( 10, 10 ) - - def _get_key( self, event ): - if event.isAutoRepeat(): - return None - if event.key() < 256: - key = str(event.text()) - elif event.key() in self.keyvald: - key = self.keyvald[ event.key() ] - else: - key = None - - return key - - def new_timer(self, *args, **kwargs): - """ - Creates a new backend-specific subclass of :class:`backend_bases.Timer`. - This is useful for getting periodic events through the backend's native - event loop. Implemented only for backends with GUIs. - - optional arguments: - - *interval* - Timer interval in milliseconds - *callbacks* - Sequence of (func, args, kwargs) where func(*args, **kwargs) will - be executed by the timer every *interval*. - """ - return TimerQT(*args, **kwargs) - - def flush_events(self): - QtGui.qApp.processEvents() - - def start_event_loop(self,timeout): - FigureCanvasBase.start_event_loop_default(self,timeout) - start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ - - def stop_event_loop(self): - FigureCanvasBase.stop_event_loop_default(self) - stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ - - def draw_idle(self): - 'update drawing area only if idle' - d = self._idle - self._idle = False - def idle_draw(*args): - self.draw() - self._idle = True - if d: QtCore.QTimer.singleShot(0, idle_draw) - -class MainWindowQt(QtGui.QMainWindow): - def __init__(self): - QtGui.QMainWindow.__init__(self) - -class FigureManagerQT( FigureManagerBase ): - """ - Public attributes - - canvas : The FigureCanvas instance - num : The Figure number - toolbar : The qt.QToolBar - window : The qt.QMainWindow - """ - - def __init__( self, canvas, num ): - if DEBUG: print 'FigureManagerQT.%s' % fn_name() - FigureManagerBase.__init__( self, canvas, num ) - self.canvas = canvas - self.window = MainWindowQt() - self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose) - - self.window.setWindowTitle("Figure %d" % num) - image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' ) - self.window.setWindowIcon(QtGui.QIcon( image )) - - # Give the keyboard focus to the figure instead of the manager - self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) - self.canvas.setFocus() - - QtCore.QObject.connect( self.window, QtCore.SIGNAL( 'destroyed()' ), - self._widgetclosed ) - self.window._destroying = False - - self.toolbar = self._get_toolbar(self.canvas, self.window) - if self.toolbar is not None: - self.window.addToolBar(self.toolbar) - # TODO MeVis - #QtCore.QObject.connect(self.toolbar, QtCore.SIGNAL("message"), - # self._show_message) - tbs_height = self.toolbar.sizeHint.height() - else: - tbs_height = 0 - - # resize the main window so it will display the canvas with the - # requested size: - cs = canvas.sizeHint() - sbs = self.window.statusBar().sizeHint - self.window.resize(cs.width(), cs.height()+tbs_height+sbs.height()) - - self.window.setCentralWidget(self.canvas) - - if matplotlib.is_interactive(): - self.window.show() - - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: self.window.show() - - def notify_axes_change( fig ): - # This will be called whenever the current axes is changed - if self.toolbar is not None: - self.toolbar.update() - self.canvas.figure.add_axobserver( notify_axes_change ) - - def _show_message(self,s): - # Fixes a PySide segfault. - self.window.statusBar().showMessage(s) - - def _widgetclosed( self ): - if self.window._destroying: return - self.window._destroying = True - try: - Gcf.destroy(self.num) - except AttributeError: - pass - # It seems that when the python session is killed, - # Gcf can get destroyed before the Gcf.destroy - # line is run, leading to a useless AttributeError. - - - def _get_toolbar(self, canvas, parent): - # must be inited after the window, drawingArea and figure - # attrs are set - if matplotlib.rcParams['toolbar'] == 'classic': - print "Classic toolbar is not supported" - elif matplotlib.rcParams['toolbar'] == 'toolbar2': - toolbar = NavigationToolbar2QT(canvas, parent, False) - else: - toolbar = None - return toolbar - - def resize(self, width, height): - 'set the canvas size in pixels' - self.window.resize(width, height) - - def show(self): - self.window.show() - - def destroy( self, *args ): - if self.window._destroying: return - self.window._destroying = True - QtCore.QObject.disconnect( self.window, QtCore.SIGNAL( 'destroyed()' ), - self._widgetclosed ) - if self.toolbar: self.toolbar.destroy() - if DEBUG: print "destroy figure manager" - self.window.close() - - def set_window_title(self, title): - self.window.setWindowTitle(title) - -class NavigationToolbar2QT( NavigationToolbar2, QtGui.QToolBar ): - def __init__(self, canvas, parent, coordinates=True): - """ coordinates: should we show the coordinates on the right? """ - self.canvas = canvas - self.coordinates = coordinates - QtGui.QToolBar.__init__( self, parent ) - NavigationToolbar2.__init__( self, canvas ) - - def _icon(self, name): - return QtGui.QIcon(os.path.join(self.basedir, name)) - - def _init_toolbar(self): - self.basedir = os.path.join(matplotlib.rcParams[ 'datapath' ],'images') - - a = self.addAction(self._icon('home.png'), 'Home', self.home) - a.setToolTip('Reset original view') - a = self.addAction(self._icon('back.png'), 'Back', self.back) - a.setToolTip('Back to previous view') - a = self.addAction(self._icon('forward.png'), 'Forward', self.forward) - a.setToolTip('Forward to next view') - self.addSeparator() - a = self.addAction(self._icon('move.png'), 'Pan', self.pan) - a.setToolTip('Pan axes with left mouse, zoom with right') - a = self.addAction(self._icon('zoom_to_rect.png'), 'Zoom', self.zoom) - a.setToolTip('Zoom to rectangle') - self.addSeparator() - a = self.addAction(self._icon('subplots.png'), 'Subplots', - self.configure_subplots) - a.setToolTip('Configure subplots') - - if figureoptions is not None: - a = self.addAction(self._icon("qt4_editor_options.png"), - 'Customize', self.edit_parameters) - a.setToolTip('Edit curves line and axes parameters') - - a = self.addAction(self._icon('filesave.png'), 'Save', - self.save_figure) - a.setToolTip('Save the figure') - - - self.buttons = {} - - # 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. - if self.coordinates: - self.locLabel = QtGui.QLabel( "", self ) - self.locLabel.setAlignment( - QtCore.Qt.AlignRight | QtCore.Qt.AlignTop ) - self.locLabel.setSizePolicy( - QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, - QtGui.QSizePolicy.Ignored)) - labelAction = self.addWidget(self.locLabel) - labelAction.setVisible(True) - - # reference holder for subplots_adjust window - self.adj_window = None - - if figureoptions is not None: - def edit_parameters(self): - allaxes = self.canvas.figure.get_axes() - if len(allaxes) == 1: - axes = allaxes[0] - else: - titles = [] - for axes in allaxes: - title = axes.get_title() - ylabel = axes.get_ylabel() - if title: - fmt = "%(title)s" - if ylabel: - fmt += ": %(ylabel)s" - fmt += " (%(axes_repr)s)" - elif ylabel: - fmt = "%(axes_repr)s (%(ylabel)s)" - else: - fmt = "%(axes_repr)s" - titles.append(fmt % dict(title = title, - ylabel = ylabel, - axes_repr = repr(axes))) - item, ok = QtGui.QInputDialog.getItem(self, 'Customize', - 'Select axes:', titles, - 0, False) - if ok: - axes = allaxes[titles.index(unicode(item))] - else: - return - - figureoptions.figure_edit(axes, self) - - - def dynamic_update( self ): - self.canvas.draw() - - def set_message( self, s ): - # TODO MeVis - #self.emit(QtCore.SIGNAL("message"), s) - if self.coordinates: - self.locLabel.setText(s.replace(', ', '\n')) - - 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 configure_subplots(self): - self.adj_window = QtGui.QMainWindow() - win = self.adj_window - win.setAttribute(QtCore.Qt.WA_DeleteOnClose) - - win.setWindowTitle("Subplot Configuration Tool") - image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' ) - win.setWindowIcon(QtGui.QIcon( image )) - - tool = SubplotToolQt(self.canvas.figure, win) - win.setCentralWidget(tool) - win.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) - - win.show() - - def _get_canvas(self, fig): - return FigureCanvasQT(fig) - - def save_figure(self, *args): - filetypes = self.canvas.get_supported_filetypes_grouped() - sorted_filetypes = filetypes.items() - sorted_filetypes.sort() - default_filetype = self.canvas.get_default_filetype() - - start = "image." + default_filetype - filters = [] - selectedFilter = None - for name, exts in sorted_filetypes: - exts_list = " ".join(['*.%s' % ext for ext in exts]) - filter = '%s (%s)' % (name, exts_list) - if default_filetype in exts: - selectedFilter = filter - filters.append(filter) - filters = ';;'.join(filters) - - fname = _getSaveFileName(self, "Choose a filename to save to", - start, filters, selectedFilter) - if fname: - try: - self.canvas.print_figure( unicode(fname) ) - except Exception, e: - QtGui.QMessageBox.critical( - self, "Error saving file", str(e), - QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton) - - - -class SubplotToolQt( SubplotTool, QtGui.QWidget ): - def __init__(self, targetfig, parent): - QtGui.QWidget.__init__(self, None) - - self.targetfig = targetfig - self.setParent(parent) - - self.sliderleft = QtGui.QSlider(QtCore.Qt.Horizontal) - self.sliderbottom = QtGui.QSlider(QtCore.Qt.Vertical) - self.sliderright = QtGui.QSlider(QtCore.Qt.Horizontal) - self.slidertop = QtGui.QSlider(QtCore.Qt.Vertical) - self.sliderwspace = QtGui.QSlider(QtCore.Qt.Horizontal) - self.sliderhspace = QtGui.QSlider(QtCore.Qt.Vertical) - - # constraints - QtCore.QObject.connect( self.sliderleft, - QtCore.SIGNAL( "valueChanged(int)" ), - self.sliderright.setMinimum ) - QtCore.QObject.connect( self.sliderright, - QtCore.SIGNAL( "valueChanged(int)" ), - self.sliderleft.setMaximum ) - QtCore.QObject.connect( self.sliderbottom, - QtCore.SIGNAL( "valueChanged(int)" ), - self.slidertop.setMinimum ) - QtCore.QObject.connect( self.slidertop, - QtCore.SIGNAL( "valueChanged(int)" ), - self.sliderbottom.setMaximum ) - - sliders = (self.sliderleft, self.sliderbottom, self.sliderright, - self.slidertop, self.sliderwspace, self.sliderhspace, ) - adjustments = ('left:', 'bottom:', 'right:', 'top:', 'wspace:', 'hspace:') - - for slider, adjustment in zip(sliders, adjustments): - slider.setMinimum(0) - slider.setMaximum(1000) - slider.setSingleStep(5) - - layout = QtGui.QGridLayout() - self.setLayout(layout) - - leftlabel = QtGui.QLabel('left') - layout.addWidget(leftlabel, 2, 0) - layout.addWidget(self.sliderleft, 2, 1) - - toplabel = QtGui.QLabel('top') - layout.addWidget(toplabel, 0, 2) - layout.addWidget(self.slidertop, 1, 2) - layout.setAlignment(self.slidertop, QtCore.Qt.AlignHCenter) - - bottomlabel = QtGui.QLabel('bottom') - layout.addWidget(QtGui.QLabel('bottom'), 4, 2) - layout.addWidget(self.sliderbottom, 3, 2) - layout.setAlignment(self.sliderbottom, QtCore.Qt.AlignHCenter) - - rightlabel = QtGui.QLabel('right') - layout.addWidget(rightlabel, 2, 4) - layout.addWidget(self.sliderright, 2, 3) - - hspacelabel = QtGui.QLabel('hspace') - layout.addWidget(hspacelabel, 0, 6) - layout.setAlignment(hspacelabel, QtCore.Qt.AlignHCenter) - layout.addWidget(self.sliderhspace, 1, 6) - layout.setAlignment(self.sliderhspace, QtCore.Qt.AlignHCenter) - - wspacelabel = QtGui.QLabel('wspace') - layout.addWidget(wspacelabel, 4, 6) - layout.setAlignment(wspacelabel, QtCore.Qt.AlignHCenter) - layout.addWidget(self.sliderwspace, 3, 6) - layout.setAlignment(self.sliderwspace, QtCore.Qt.AlignBottom) - - layout.setRowStretch(1,1) - layout.setRowStretch(3,1) - layout.setColumnStretch(1,1) - layout.setColumnStretch(3,1) - layout.setColumnStretch(6,1) - - - - self.sliderleft.setSliderPosition(int(targetfig.subplotpars.left*1000)) - self.sliderbottom.setSliderPosition(\ - int(targetfig.subplotpars.bottom*1000)) - self.sliderright.setSliderPosition(\ - int(targetfig.subplotpars.right*1000)) - self.slidertop.setSliderPosition(int(targetfig.subplotpars.top*1000)) - self.sliderwspace.setSliderPosition(\ - int(targetfig.subplotpars.wspace*1000)) - self.sliderhspace.setSliderPosition(\ - int(targetfig.subplotpars.hspace*1000)) - - QtCore.QObject.connect( self.sliderleft, - QtCore.SIGNAL( "valueChanged(int)" ), - self.funcleft ) - QtCore.QObject.connect( self.sliderbottom, - QtCore.SIGNAL( "valueChanged(int)" ), - self.funcbottom ) - QtCore.QObject.connect( self.sliderright, - QtCore.SIGNAL( "valueChanged(int)" ), - self.funcright ) - QtCore.QObject.connect( self.slidertop, - QtCore.SIGNAL( "valueChanged(int)" ), - self.functop ) - QtCore.QObject.connect( self.sliderwspace, - QtCore.SIGNAL( "valueChanged(int)" ), - self.funcwspace ) - QtCore.QObject.connect( self.sliderhspace, - QtCore.SIGNAL( "valueChanged(int)" ), - self.funchspace ) - - def funcleft(self, val): - if val == self.sliderright.value: - val -= 1 - self.targetfig.subplots_adjust(left=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - def funcright(self, val): - if val == self.sliderleft.value: - val += 1 - self.targetfig.subplots_adjust(right=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - def funcbottom(self, val): - if val == self.slidertop.value: - val -= 1 - self.targetfig.subplots_adjust(bottom=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - def functop(self, val): - if val == self.sliderbottom.value: - val += 1 - self.targetfig.subplots_adjust(top=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - def funcwspace(self, val): - self.targetfig.subplots_adjust(wspace=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - def funchspace(self, val): - self.targetfig.subplots_adjust(hspace=val/1000.) - if self.drawon: self.targetfig.canvas.draw() - - -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 - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: o8NAAdQX11plvQl1dRRQmr299ycvASXljWXu74amG7/IkI8BFdxh1Gx9QWmqfuVEdy7pjRavr90n6N1KbLs5BA== -#//# MeVis end diff --git a/matplotlib/backends/backend_qt4agg.py b/matplotlib/backends/backend_qt4agg.py deleted file mode 100644 index 047f3d95..00000000 --- a/matplotlib/backends/backend_qt4agg.py +++ /dev/null @@ -1,142 +0,0 @@ -""" -Render to qt from agg -""" -from __future__ import division - -import os, sys - -import matplotlib -from matplotlib.figure import Figure - -from backend_agg import FigureCanvasAgg -from backend_qt4 import QtCore, QtGui, FigureManagerQT, FigureCanvasQT,\ - show, draw_if_interactive, backend_version, \ - NavigationToolbar2QT - -DEBUG = False - - -def new_figure_manager( num, *args, **kwargs ): - """ - Create a new figure manager instance - """ - if DEBUG: print 'backend_qtagg.new_figure_manager' - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQTAgg( thisFig ) - return FigureManagerQT( canvas, num ) - -class NavigationToolbar2QTAgg(NavigationToolbar2QT): - def _get_canvas(self, fig): - return FigureCanvasQTAgg(fig) - -class FigureManagerQTAgg(FigureManagerQT): - def _get_toolbar(self, canvas, parent): - # must be inited after the window, drawingArea and figure - # attrs are set - if matplotlib.rcParams['toolbar']=='classic': - print "Classic toolbar is not supported" - elif matplotlib.rcParams['toolbar']=='toolbar2': - toolbar = NavigationToolbar2QTAgg(canvas, parent) - else: - toolbar = None - return toolbar - -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.rectangle = [] - self.blitbox = None - self.replot = True - self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent) - - def drawRectangle( self, rect ): - self.rectangle = rect - self.drawRect = True - self.repaint( ) - - def paintEvent( self, e ): - """ - Draw to the Agg backend and then copy the image to the qt.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, \ - self.get_width_height() - - if self.replot: - FigureCanvasAgg.draw(self) - self.replot = False - - if self.blitbox is None: - - stringBuffer = self.renderer._renderer.tostring_bgra() - qImage = QtGui.QImage(stringBuffer, self.renderer.width, - self.renderer.height, - QtGui.QImage.Format_ARGB32) - p = QtGui.QPainter(self) - p.drawPixmap(QtCore.QPoint(0, 0), QtGui.QPixmap.fromImage(qImage)) - - # draw the zoom rectangle to the QPainter - if self.drawRect: - p.setPen( QtGui.QPen( QtCore.Qt.black, 1, QtCore.Qt.DotLine ) ) - p.drawRect( self.rectangle[0], self.rectangle[1], self.rectangle[2], self.rectangle[3] ) - p.end() - else: - bbox = self.blitbox - l, b, r, t = bbox.extents - w = int(r) - int(l) - h = int(t) - int(b) - t = int(b) + h - reg = self.copy_from_bbox(bbox) - stringBuffer = reg.tostring_bgra() - qImage = QtGui.QImage(stringBuffer, w, h, QtGui.QImage.Format_ARGB32) - pixmap = QtGui.QPixmap.fromImage(qImage) - p = QtGui.QPainter( self ) - p.drawPixmap(QtCore.QPoint(l, self.renderer.height-t), pixmap) - p.end() - self.blitbox = None - self.drawRect = False - - def draw( self ): - """ - Draw the figure when xwindows is ready for the update - """ - - if DEBUG: print "FigureCanvasQtAgg.draw", self - self.replot = True - self.update() - - def blit(self, bbox=None): - """ - Blit the region in bbox - """ - self.blitbox = bbox - l, b, w, h = bbox.bounds - t = b + h - self.repaint(l, self.renderer.height-t, w, h) - - def print_figure(self, *args, **kwargs): - FigureCanvasAgg.print_figure(self, *args, **kwargs) - self.draw() - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: ZC3LgiLKPvWaU70dtjhl7mFyYUjNiEUTffZvqz2g26norkMmypeWPIZ3CFBlFg0jRkuF47HTY0RY6g9+SepY4Q== -#//# MeVis end diff --git a/matplotlib/backends/backend_qtagg.py b/matplotlib/backends/backend_qtagg.py deleted file mode 100644 index cea017d6..00000000 --- a/matplotlib/backends/backend_qtagg.py +++ /dev/null @@ -1,157 +0,0 @@ -""" -Render to qt from agg -""" -from __future__ import division - -import os, sys -import matplotlib -from matplotlib import verbose -from matplotlib.figure import Figure - -from backend_agg import FigureCanvasAgg -from backend_qt import qt, FigureManagerQT, FigureCanvasQT,\ - show, draw_if_interactive, backend_version, \ - NavigationToolbar2QT - -DEBUG = False - - -def new_figure_manager( num, *args, **kwargs ): - """ - Create a new figure manager instance - """ - if DEBUG: print 'backend_qtagg.new_figure_manager' - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQTAgg( thisFig ) - return FigureManagerQTAgg( canvas, num ) - -class NavigationToolbar2QTAgg(NavigationToolbar2QT): - def _get_canvas(self, fig): - return FigureCanvasQTAgg(fig) - -class FigureManagerQTAgg(FigureManagerQT): - def _get_toolbar(self, canvas, parent): - # must be inited after the window, drawingArea and figure - # attrs are set - if matplotlib.rcParams['toolbar']=='classic': - print "Classic toolbar is not yet supported" - elif matplotlib.rcParams['toolbar']=='toolbar2': - toolbar = NavigationToolbar2QTAgg(canvas, parent) - else: - toolbar = None - return toolbar - -class FigureCanvasQTAgg( FigureCanvasAgg, FigureCanvasQT ): - """ - 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 = qt.QPixmap() - - def resizeEvent( self, e ): - FigureCanvasQT.resizeEvent( self, e ) - - def drawRectangle( self, rect ): - self.rect = rect - self.drawRect = True - # False in repaint does not clear the image before repainting - self.repaint( False ) - - def paintEvent( self, e ): - """ - Draw to the Agg backend and then copy the image to the qt.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, \ - self.get_width_height() - - p = qt.QPainter( self ) - - # only replot data when needed - if type(self.replot) is bool: # might be a bbox for blitting - if self.replot: - FigureCanvasAgg.draw( self ) - #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). - if ( qt.QImage.systemByteOrder() == qt.QImage.LittleEndian ): - stringBuffer = self.renderer._renderer.tostring_bgra() - else: - stringBuffer = self.renderer._renderer.tostring_argb() - - qImage = qt.QImage( stringBuffer, self.renderer.width, - self.renderer.height, 32, None, 0, - qt.QImage.IgnoreEndian ) - - self.pixmap.convertFromImage( qImage, qt.QPixmap.Color ) - - p.drawPixmap( qt.QPoint( 0, 0 ), self.pixmap ) - - # draw the zoom rectangle to the QPainter - if ( self.drawRect ): - p.setPen( qt.QPen( qt.Qt.black, 1, qt.Qt.DotLine ) ) - p.drawRect( self.rect[0], self.rect[1], self.rect[2], self.rect[3] ) - - # we are blitting here - else: - bbox = self.replot - l, b, r, t = bbox.extents - w = int(r) - int(l) - h = int(t) - int(b) - reg = self.copy_from_bbox(bbox) - stringBuffer = reg.to_string_argb() - qImage = qt.QImage(stringBuffer, w, h, 32, None, 0, qt.QImage.IgnoreEndian) - self.pixmap.convertFromImage(qImage, qt.QPixmap.Color) - p.drawPixmap(qt.QPoint(l, self.renderer.height-t), self.pixmap) - - 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 - self.replot = True - FigureCanvasAgg.draw(self) - self.repaint(False) - - def blit(self, bbox=None): - """ - Blit the region in bbox - """ - - self.replot = bbox - self.repaint(False) - - def print_figure(self, *args, **kwargs): - FigureCanvasAgg.print_figure(self, *args, **kwargs) - self.draw() - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: KpXCe/j3tdNQq2WzmbJ4V0g9JziJl39ca5FeTEOsDH40gT6Ahj2LnBratO1Adst6btbt2AMNe/yY+yk4FsG4iQ== -#//# MeVis end diff --git a/matplotlib/backends/qt4_compat.py b/matplotlib/backends/qt4_compat.py deleted file mode 100644 index 6e1f11f9..00000000 --- a/matplotlib/backends/qt4_compat.py +++ /dev/null @@ -1,114 +0,0 @@ -""" A Qt API selector that can be used to switch between PyQt and PySide. -""" - -import os -from matplotlib import rcParams, verbose - -# Available APIs. -QT_API_PythonQt = 'PythonQt' -QT_API_PYQT = 'PyQt4' # API is not set here; Python 2.x default is V 1 -QT_API_PYQTv2 = 'PyQt4v2' # forced to Version 2 API -QT_API_PYSIDE = 'PySide' # only supports Version 2 API - -ETS = dict(pyqt=QT_API_PYQTv2, pyside=QT_API_PYSIDE) - -# If the ETS QT_API environment variable is set, use it. Note that -# ETS requires the version 2 of PyQt4, which is not the platform -# default for Python 2.x. - -QT_API_SET = False -try: - import PythonQt - QT_API = 'PythonQt' - QT_API_SET = True -except: - pass - -if not QT_API_SET: - QT_API_ENV = os.environ.get('QT_API') - if QT_API_ENV is not None: - try: - QT_API = ETS[QT_API_ENV] - except KeyError: - raise RuntimeError( - 'Unrecognized environment variable %r, valid values are: %r or %r' % - (QT_API_ENV, 'pyqt', 'pyside')) - else: - # No ETS environment, so use rcParams. - QT_API = rcParams['backend.qt4'] - -# We will define an appropriate wrapper for the differing versions -# of file dialog. -_getSaveFileName = None - -# Now perform the imports. -if QT_API in (QT_API_PYQT, QT_API_PYQTv2): - import sip - if QT_API == QT_API_PYQTv2: - if QT_API_ENV == 'pyqt': - cond = ("Found 'QT_API=pyqt' environment variable. " - "Setting PyQt4 API accordingly.\n") - else: - cond = "PyQt API v2 specified." - try: - sip.setapi('QString', 2) - except: - res = 'QString API v2 specification failed. Defaulting to v1.' - verbose.report(cond+res, 'helpful') - # condition has now been reported, no need to repeat it: - cond = "" - try: - sip.setapi('QVariant', 2) - except: - res = 'QVariant API v2 specification failed. Defaulting to v1.' - verbose.report(cond+res, 'helpful') - - from PyQt4 import QtCore, QtGui - - # Alias PyQt-specific functions for PySide compatibility. - QtCore.Signal = QtCore.pyqtSignal - try: - QtCore.Slot = QtCore.pyqtSlot - except AttributeError: - QtCore.Slot = pyqtSignature # Not a perfect match but - # works in simple cases - QtCore.Property = QtCore.pyqtProperty - __version__ = QtCore.PYQT_VERSION_STR - - try : - if sip.getapi("QString") > 1 : - # Use new getSaveFileNameAndFilter() - _get_save = QtGui.QFileDialog.getSaveFileNameAndFilter - else : - # Use old getSaveFileName() - _getSaveFileName = QtGui.QFileDialog.getSaveFileName - except (AttributeError, KeyError) : - # call to getapi() can fail in older versions of sip - _getSaveFileName = QtGui.QFileDialog.getSaveFileName - -elif QT_API == QT_API_PYSIDE: # can only be pyside - from PySide import QtCore, QtGui, __version__, __version_info__ - if __version_info__ < (1,0,3): - raise ImportError( - "Matplotlib backend_qt4 and backend_qt4agg require PySide >=1.0.3") - - _get_save = QtGui.QFileDialog.getSaveFileName -else: - from PythonQt import QtCore, QtGui - __version__ = "2.0" - __version_info__ = "-" - # TODO MEVIS: not yet corrected: - _get_save = QtGui.QFileDialog.getSaveFileName - -if _getSaveFileName is None: - - def _getSaveFileName(self, msg, start, filters, selectedFilter): - return _get_save(self, msg, start, filters, selectedFilter) - - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: nXI1QqftPhcHQbbkjVIaj/D4gJsooQTtiJi8CPmzfpsDh8b+WiWX6gEdOJfpJZmSgYJzMPHn9djGqJcf6bPAGw== -#//# MeVis end diff --git a/matplotlib/backends/qt4_editor/__init__.py b/matplotlib/backends/qt4_editor/__init__.py deleted file mode 100644 index a4e231a8..00000000 --- a/matplotlib/backends/qt4_editor/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: ednUuf6C6zebOVMlDUXHDuI53MpaKezSixjc9Yt7TyVG67NuVYlH4sAEHQBKSWVb9CNhgTas98QxUgsor8ac9w== -#//# MeVis end diff --git a/matplotlib/backends/qt4_editor/figureoptions.py b/matplotlib/backends/qt4_editor/figureoptions.py deleted file mode 100644 index c363ca1c..00000000 --- a/matplotlib/backends/qt4_editor/figureoptions.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright © 2009 Pierre Raybaut -# Licensed under the terms of the MIT License -# see the mpl licenses directory for a copy of the license - -"""Module that provides a GUI-based editor for matplotlib's figure options""" - -import os.path as osp - -import matplotlib.backends.qt4_editor.formlayout as formlayout -from matplotlib.backends.qt4_compat import QtGui -from matplotlib import markers - -def get_icon(name): - import matplotlib - basedir = osp.join(matplotlib.rcParams['datapath'], 'images') - return QtGui.QIcon(osp.join(basedir, name)) - -LINESTYLES = { - '-': 'Solid', - '--': 'Dashed', - '-.': 'DashDot', - ':': 'Dotted', - 'steps': 'Steps', - 'none': 'None', - } - -MARKERS = markers.MarkerStyle.markers - -COLORS = {'b': '#0000ff', 'g': '#00ff00', 'r': '#ff0000', 'c': '#ff00ff', - 'm': '#ff00ff', 'y': '#ffff00', 'k': '#000000', 'w': '#ffffff'} - -def col2hex(color): - """Convert matplotlib color to hex""" - return COLORS.get(color, color) - -def figure_edit(axes, parent=None): - """Edit matplotlib figure options""" - sep = (None, None) # separator - - has_curve = len(axes.get_lines()) > 0 - - # Get / General - xmin, xmax = axes.get_xlim() - ymin, ymax = axes.get_ylim() - general = [('Title', axes.get_title()), - sep, - (None, "X-Axis"), - ('Min', xmin), ('Max', xmax), - ('Label', axes.get_xlabel()), - ('Scale', [axes.get_xscale(), 'linear', 'log']), - sep, - (None, "Y-Axis"), - ('Min', ymin), ('Max', ymax), - ('Label', axes.get_ylabel()), - ('Scale', [axes.get_yscale(), 'linear', 'log']) - ] - - if has_curve: - # Get / Curves - linedict = {} - for line in axes.get_lines(): - label = line.get_label() - if label == '_nolegend_': - continue - linedict[label] = line - curves = [] - linestyles = LINESTYLES.items() - markers = MARKERS.items() - curvelabels = sorted(linedict.keys()) - for label in curvelabels: - line = linedict[label] - curvedata = [ - ('Label', label), - sep, - (None, 'Line'), - ('Style', [line.get_linestyle()] + linestyles), - ('Width', line.get_linewidth()), - ('Color', col2hex(line.get_color())), - sep, - (None, 'Marker'), - ('Style', [line.get_marker()] + markers), - ('Size', line.get_markersize()), - ('Facecolor', col2hex(line.get_markerfacecolor())), - ('Edgecolor', col2hex(line.get_markeredgecolor())), - ] - curves.append([curvedata, label, ""]) - - datalist = [(general, "Axes", "")] - if has_curve: - datalist.append((curves, "Curves", "")) - - def apply_callback(data): - """This function will be called to apply changes""" - if has_curve: - general, curves = data - else: - general, = data - - # Set / General - title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale = general - axes.set_xscale(xscale) - axes.set_yscale(yscale) - axes.set_title(title) - axes.set_xlim(xmin, xmax) - axes.set_xlabel(xlabel) - axes.set_ylim(ymin, ymax) - axes.set_ylabel(ylabel) - - if has_curve: - # Set / Curves - for index, curve in enumerate(curves): - line = linedict[curvelabels[index]] - label, linestyle, linewidth, color, \ - marker, markersize, markerfacecolor, markeredgecolor = curve - line.set_label(label) - line.set_linestyle(linestyle) - line.set_linewidth(linewidth) - line.set_color(color) - if marker is not 'none': - line.set_marker(marker) - line.set_markersize(markersize) - line.set_markerfacecolor(markerfacecolor) - line.set_markeredgecolor(markeredgecolor) - - # Redraw - figure = axes.get_figure() - figure.canvas.draw() - - data = formlayout.fedit(datalist, title="Figure options", parent=parent, - icon=get_icon('qt4_editor_options.svg'), apply=apply_callback) - if data is not None: - apply_callback(data) - - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: QeTyV12lK8ph4TMJhIc44iIMHkjKRHyrcoACbaBUgLlLr08hxTyPWBUm92BaB4uE+oL+Y+QEHf9YiA206rmnAQ== -#//# MeVis end diff --git a/matplotlib/backends/qt4_editor/formlayout.py b/matplotlib/backends/qt4_editor/formlayout.py deleted file mode 100644 index e38ae773..00000000 --- a/matplotlib/backends/qt4_editor/formlayout.py +++ /dev/null @@ -1,569 +0,0 @@ -# -*- coding: utf-8 -*- -""" -formlayout -========== - -Module creating Qt form dialogs/layouts to edit various type of parameters - - -formlayout License Agreement (MIT License) ------------------------------------------- - -Copyright (c) 2009 Pierre Raybaut - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -""" - -# History: -# 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid) -# 1.0.7: added support for "Apply" button -# 1.0.6: code cleaning - -__version__ = '1.0.10' -__license__ = __doc__ - -DEBUG = False - -import sys -STDERR = sys.stderr - -from matplotlib.backends.qt4_compat import QtGui,QtCore -if not hasattr(QtGui,'QFormLayout'): - raise ImportError, "Warning: formlayout requires PyQt4 >v4.3 or PySide" - -(QWidget, QLineEdit, QComboBox, QLabel, QSpinBox, QIcon,QStyle, - QDialogButtonBox, QHBoxLayout, QVBoxLayout, QDialog, QColor, QPushButton, - QCheckBox, QColorDialog, QPixmap, QTabWidget, QApplication, QStackedWidget, - QDateEdit, QDateTimeEdit, QFont, QFontComboBox, QFontDatabase, QGridLayout, - QFormLayout, QDoubleValidator) =\ - (QtGui.QWidget, QtGui.QLineEdit, QtGui.QComboBox, QtGui.QLabel, - QtGui.QSpinBox, QtGui.QIcon, QtGui.QStyle, QtGui.QDialogButtonBox, - QtGui.QHBoxLayout, QtGui.QVBoxLayout, QtGui.QDialog, QtGui.QColor, - QtGui.QPushButton, QtGui.QCheckBox, QtGui.QColorDialog, QtGui.QPixmap, - QtGui.QTabWidget, QtGui.QApplication, QtGui.QStackedWidget, QtGui.QDateEdit, - QtGui.QDateTimeEdit, QtGui.QFont, QtGui.QFontComboBox, None, # TODO MEVIS - QtGui.QGridLayout, QtGui.QFormLayout, QtGui.QDoubleValidator) - -(Qt, SIGNAL, SLOT, QObject, QSize,pyqtSignature, pyqtProperty) =\ -(QtCore.Qt, QtCore.SIGNAL, QtCore.SLOT, QtCore.QObject, QtCore.QSize, - None, None) # TODO MEVIS - -import datetime - -class ColorButton(QPushButton): - """ - Color choosing push button - """ - __pyqtSignals__ = ("colorChanged(QColor)",) - - def __init__(self, parent=None): - QPushButton.__init__(self, parent) - self.setFixedSize(20, 20) - self.setIconSize(QSize(12, 12)) - self.connect(self, SIGNAL("clicked()"), self.choose_color) - self._color = QColor() - - def choose_color(self): - color = QColorDialog.getColor(self._color,self.parentWidget(),'') - if color.isValid(): - self.set_color(color) - - def get_color(self): - return self._color -# TODO MEVIS -# @pyqtSignature("QColor") -# def set_color(self, color): -# if color != self._color: -# self._color = color -# self.emit(SIGNAL("colorChanged(QColor)"), self._color) -# pixmap = QPixmap(self.iconSize()) -# pixmap.fill(color) -# self.setIcon(QIcon(pixmap)) -# -# color = pyqtProperty("QColor", get_color, set_color) - - -def text_to_qcolor(text): - """ - Create a QColor from specified string - Avoid warning from Qt when an invalid QColor is instantiated - """ - color = QColor() - if isinstance(text, QObject): - # actually a QString, which is not provided by the new PyQt4 API: - text = str(text) - if not isinstance(text, (unicode, str)): - return color - if text.startswith('#') and len(text)==7: - correct = '#0123456789abcdef' - for char in text: - if char.lower() not in correct: - return color - elif text not in list(QColor.colorNames()): - return color - color.setNamedColor(text) - return color - - -class ColorLayout(QHBoxLayout): - """Color-specialized QLineEdit layout""" - def __init__(self, color, parent=None): - QHBoxLayout.__init__(self) - assert isinstance(color, QColor) - self.lineedit = QLineEdit(color.name(), parent) - self.connect(self.lineedit, SIGNAL("textChanged(QString)"), - self.update_color) - self.addWidget(self.lineedit) - self.colorbtn = ColorButton(parent) - self.colorbtn.color = color - self.connect(self.colorbtn, SIGNAL("colorChanged(QColor)"), - self.update_text) - self.addWidget(self.colorbtn) - - def update_color(self, text): - color = text_to_qcolor(text) - if color.isValid(): - self.colorbtn.color = color - - def update_text(self, color): - self.lineedit.setText(color.name()) - - def text(self): - return self.lineedit.text - - -def font_is_installed(font): - """Check if font is installed""" - return [fam for fam in QFontDatabase().families() if unicode(fam)==font] - -def tuple_to_qfont(tup): - """ - Create a QFont from tuple: - (family [string], size [int], italic [bool], bold [bool]) - """ - if not isinstance(tup, tuple) or len(tup) != 4 \ - or not font_is_installed(tup[0]) \ - or not isinstance(tup[1], int) \ - or not isinstance(tup[2], bool) \ - or not isinstance(tup[3], bool): - return None - font = QFont() - family, size, italic, bold = tup - font.setFamily(family) - font.setPointSize(size) - font.setItalic(italic) - font.setBold(bold) - return font - -def qfont_to_tuple(font): - return (unicode(font.family()), int(font.pointSize()), - font.italic(), font.bold()) - -class FontLayout(QGridLayout): - """Font selection""" - def __init__(self, value, parent=None): - QGridLayout.__init__(self) - font = tuple_to_qfont(value) - assert font is not None - - # Font family - self.family = QFontComboBox(parent) - self.family.setCurrentFont(font) - self.addWidget(self.family, 0, 0, 1, -1) - - # Font size - self.size = QComboBox(parent) - self.size.setEditable(True) - sizelist = range(6, 12) + range(12, 30, 2) + [36, 48, 72] - size = font.pointSize() - if size not in sizelist: - sizelist.append(size) - sizelist.sort() - self.size.addItems([str(s) for s in sizelist]) - self.size.setCurrentIndex(sizelist.index(size)) - self.addWidget(self.size, 1, 0) - - # Italic or not - self.italic = QCheckBox(self.tr("Italic"), parent) - self.italic.setChecked(font.italic()) - self.addWidget(self.italic, 1, 1) - - # Bold or not - self.bold = QCheckBox(self.tr("Bold"), parent) - self.bold.setChecked(font.bold()) - self.addWidget(self.bold, 1, 2) - - def get_font(self): - font = self.family.currentFont() - font.setItalic(self.italic.isChecked()) - font.setBold(self.bold.isChecked()) - font.setPointSize(int(self.size.currentText())) - return qfont_to_tuple(font) - - -def is_edit_valid(edit): - text = edit.text - state = edit.validator().validate(text, 0)[0] - - return state == QDoubleValidator.Acceptable - -class FormWidget(QWidget): - def __init__(self, data, comment="", parent=None): - QWidget.__init__(self, parent) - from copy import deepcopy - self.data = deepcopy(data) - self.widgets = [] - self.formlayout = QFormLayout(self) - if comment: - self.formlayout.addRow(QLabel(comment)) - self.formlayout.addRow(QLabel(" ")) - if DEBUG: - print "\n"+("*"*80) - print "DATA:", self.data - print "*"*80 - print "COMMENT:", comment - print "*"*80 - - def get_dialog(self): - """Return FormDialog instance""" - dialog = self.parent() - while not isinstance(dialog, QDialog): - dialog = dialog.parent() - return dialog - - def setup(self): - for label, value in self.data: - if DEBUG: - print "value:", value - if label is None and value is None: - # Separator: (None, None) - self.formlayout.addRow(QLabel(" "), QLabel(" ")) - self.widgets.append(None) - continue - elif label is None: - # Comment - self.formlayout.addRow(QLabel(value)) - self.widgets.append(None) - continue - elif tuple_to_qfont(value) is not None: - field = FontLayout(value, self) - elif text_to_qcolor(value).isValid(): - field = ColorLayout(QColor(value), self) - elif isinstance(value, (str, unicode)): - field = QLineEdit(value, self) - elif isinstance(value, (list, tuple)): - selindex = value.pop(0) - field = QComboBox(self) - if isinstance(value[0], (list, tuple)): - keys = [ key for key, _val in value ] - value = [ val for _key, val in value ] - else: - keys = value - field.addItems(value) - if selindex in value: - selindex = value.index(selindex) - elif selindex in keys: - selindex = keys.index(selindex) - elif not isinstance(selindex, int): - print >>STDERR, "Warning: '%s' index is invalid (label: " \ - "%s, value: %s)" % (selindex, label, value) - selindex = 0 - field.setCurrentIndex(selindex) - elif isinstance(value, bool): - field = QCheckBox(self) - if value : - field.setCheckState(Qt.Checked) - else : - field.setCheckState(Qt.Unchecked) - elif isinstance(value, float): - field = QLineEdit(repr(value), self) - field.setValidator(QDoubleValidator(field)) - dialog = self.get_dialog() - dialog.register_float_field(field) - self.connect(field, SIGNAL('textChanged(QString)'), - lambda text: dialog.update_buttons()) - elif isinstance(value, int): - field = QSpinBox(self) - field.setRange(-1e9, 1e9) - field.setValue(value) - elif isinstance(value, datetime.datetime): - field = QDateTimeEdit(self) - field.setDateTime(value) - elif isinstance(value, datetime.date): - field = QDateEdit(self) - field.setDate(value) - else: - field = QLineEdit(repr(value), self) - self.formlayout.addRow(label, field) - self.widgets.append(field) - - def get(self): - valuelist = [] - for index, (label, value) in enumerate(self.data): - field = self.widgets[index] - if label is None: - # Separator / Comment - continue - elif tuple_to_qfont(value) is not None: - value = field.get_font() - elif isinstance(value, (str, unicode)): - if isinstance(field, ColorLayout): - value = unicode(field.text()) - else: - value = unicode(field.text) - elif isinstance(value, (list, tuple)): - index = int(field.currentIndex) - if isinstance(value[0], (list, tuple)): - value = value[index][0] - else: - value = value[index] - elif isinstance(value, bool): - value = field.checkState == Qt.Checked - elif isinstance(value, float): - value = float(field.text) - elif isinstance(value, int): - value = int(field.value) - elif isinstance(value, datetime.datetime): - value = field.dateTime().toPyDateTime() - elif isinstance(value, datetime.date): - value = field.date().toPyDate() - else: - value = eval(str(field.text)) - valuelist.append(value) - return valuelist - - -class FormComboWidget(QWidget): - def __init__(self, datalist, comment="", parent=None): - QWidget.__init__(self, parent) - layout = QVBoxLayout() - self.setLayout(layout) - self.combobox = QComboBox() - layout.addWidget(self.combobox) - - self.stackwidget = QStackedWidget(self) - layout.addWidget(self.stackwidget) - self.connect(self.combobox, SIGNAL("currentIndexChanged(int)"), - self.stackwidget, SLOT("setCurrentIndex(int)")) - - self.widgetlist = [] - for data, title, comment in datalist: - self.combobox.addItem(title) - widget = FormWidget(data, comment=comment, parent=self) - self.stackwidget.addWidget(widget) - self.widgetlist.append(widget) - - def setup(self): - for widget in self.widgetlist: - widget.setup() - - def get(self): - return [ widget.get() for widget in self.widgetlist] - - -class FormTabWidget(QWidget): - def __init__(self, datalist, comment="", parent=None): - QWidget.__init__(self, parent) - layout = QVBoxLayout() - self.tabwidget = QTabWidget() - layout.addWidget(self.tabwidget) - self.setLayout(layout) - self.widgetlist = [] - for data, title, comment in datalist: - if len(data[0])==3: - widget = FormComboWidget(data, comment=comment, parent=self) - else: - widget = FormWidget(data, comment=comment, parent=self) - index = self.tabwidget.addTab(widget, title) - self.tabwidget.setTabToolTip(index, comment) - self.widgetlist.append(widget) - - def setup(self): - for widget in self.widgetlist: - widget.setup() - - def get(self): - return [ widget.get() for widget in self.widgetlist] - - -class FormDialog(QDialog): - """Form Dialog""" - def __init__(self, data, title="", comment="", - icon=None, parent=None, apply=None): - QDialog.__init__(self, parent) - - self.apply_callback = apply - - # Form - if isinstance(data[0][0], (list, tuple)): - self.formwidget = FormTabWidget(data, comment=comment, - parent=self) - elif len(data[0])==3: - self.formwidget = FormComboWidget(data, comment=comment, - parent=self) - else: - self.formwidget = FormWidget(data, comment=comment, - parent=self) - layout = QVBoxLayout() - layout.addWidget(self.formwidget) - - self.float_fields = [] - self.formwidget.setup() - - # Button box - self.bbox = bbox = QDialogButtonBox(QDialogButtonBox.Ok - |QDialogButtonBox.Cancel) - self.connect(self.formwidget, SIGNAL('update_buttons()'), - self.update_buttons) - if self.apply_callback is not None: - apply_btn = bbox.addButton(QDialogButtonBox.Apply) - self.connect(apply_btn, SIGNAL("clicked()"), self.apply) - self.connect(bbox, SIGNAL("accepted()"), self.accept) - self.connect(bbox, SIGNAL("rejected()"), self.reject) - layout.addWidget(bbox) - - self.setLayout(layout) - - self.setWindowTitle(title) - if not isinstance(icon, QIcon): - icon = QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion) - self.setWindowIcon(icon) - - def register_float_field(self, field): - self.float_fields.append(field) - - def update_buttons(self): - valid = True - for field in self.float_fields: - if not is_edit_valid(field): - valid = False - for btn_type in (QDialogButtonBox.Ok, QDialogButtonBox.Apply): - btn = self.bbox.button(btn_type) - if btn is not None: - btn.setEnabled(valid) - - def accept(self): - self.data = self.formwidget.get() - QDialog.accept(self) - - def reject(self): - self.data = None - QDialog.reject(self) - - def apply(self): - self.apply_callback(self.formwidget.get()) - - def get(self): - """Return form result""" - return self.data - - -def fedit(data, title="", comment="", icon=None, parent=None, apply=None): - """ - Create form dialog and return result - (if Cancel button is pressed, return None) - - data: datalist, datagroup - title: string - comment: string - icon: QIcon instance - parent: parent QWidget - apply: apply callback (function) - - datalist: list/tuple of (field_name, field_value) - datagroup: list/tuple of (datalist *or* datagroup, title, comment) - - -> one field for each member of a datalist - -> one tab for each member of a top-level datagroup - -> one page (of a multipage widget, each page can be selected with a combo - box) for each member of a datagroup inside a datagroup - - Supported types for field_value: - - int, float, str, unicode, bool - - colors: in Qt-compatible text form, i.e. in hex format or name (red,...) - (automatically detected from a string) - - list/tuple: - * the first element will be the selected index (or value) - * the other elements can be couples (key, value) or only values - """ - - # Create a QApplication instance if no instance currently exists - # (e.g. if the module is used directly from the interpreter) - if QApplication.startingUp(): - _app = QApplication([]) - - dialog = FormDialog(data, title, comment, icon, parent, apply) - if dialog.exec_(): - return dialog.get() - - - -if __name__ == "__main__": - - def create_datalist_example(): - return [('str', 'this is a string'), - ('list', [0, '1', '3', '4']), - ('list2', ['--', ('none', 'None'), ('--', 'Dashed'), - ('-.', 'DashDot'), ('-', 'Solid'), - ('steps', 'Steps'), (':', 'Dotted')]), - ('float', 1.2), - (None, 'Other:'), - ('int', 12), - ('font', ('Arial', 10, False, True)), - ('color', '#123409'), - ('bool', True), - ('date', datetime.date(2010, 10, 10)), - ('datetime', datetime.datetime(2010, 10, 10)), - ] - - def create_datagroup_example(): - datalist = create_datalist_example() - return ((datalist, "Category 1", "Category 1 comment"), - (datalist, "Category 2", "Category 2 comment"), - (datalist, "Category 3", "Category 3 comment")) - - #--------- datalist example - datalist = create_datalist_example() - def apply_test(data): - print "data:", data - print "result:", fedit(datalist, title="Example", - comment="This is just an example.", - apply=apply_test) - - #--------- datagroup example - datagroup = create_datagroup_example() - print "result:", fedit(datagroup, "Global title") - - #--------- datagroup inside a datagroup example - datalist = create_datalist_example() - datagroup = create_datagroup_example() - print "result:", fedit(((datagroup, "Title 1", "Tab 1 comment"), - (datalist, "Title 2", "Tab 2 comment"), - (datalist, "Title 3", "Tab 3 comment")), - "Global title") - -#//# MeVis signature v1 -#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ== -#//# owner: MeVis -#//# date: 2012-09-29T02:59:46 -#//# hash: xNIq2m/cZeyb0cO2/Q8Uo5AOrOBErrvmtJsWrZ4nz4CPSFPX7LMNGIAttSnYLSYekzk9W5YdNw1lll3Wi/wUAQ== -#//# MeVis end