Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf0644a

Browse files
committed
Merge pull request #80 from gstorer/master
PySide backend support
2 parents a4cc50c + 69e8d2d commit cf0644a

File tree

7 files changed

+153
-73
lines changed

7 files changed

+153
-73
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
13531353

13541354

13551355

1356-
class FigureCanvasBase:
1356+
class FigureCanvasBase(object):
13571357
"""
13581358
The canvas the figure renders into.
13591359
@@ -2308,7 +2308,7 @@ class Cursors: #namespace
23082308

23092309

23102310

2311-
class NavigationToolbar2:
2311+
class NavigationToolbar2(object):
23122312
"""
23132313
Base class for the navigation cursor, version 2
23142314

lib/matplotlib/backends/backend_qt4.py

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,9 @@
2020
except ImportError:
2121
figureoptions = None
2222

23-
try:
24-
from PyQt4 import QtCore, QtGui
25-
except ImportError:
26-
raise ImportError("Qt4 backend requires that PyQt4 is installed.")
27-
28-
import sip
29-
30-
try :
31-
if sip.getapi("QString") > 1 :
32-
# Use new getSaveFileNameAndFilter()
33-
_getSaveFileName = lambda self, msg, start, filters, selectedFilter : \
34-
QtGui.QFileDialog.getSaveFileNameAndFilter(self, \
35-
msg, start, filters, selectedFilter)[0]
36-
else :
37-
# Use old getSaveFileName()
38-
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
39-
except (AttributeError, KeyError) :
40-
# call to getapi() can fail in older versions of sip
41-
# Use the old getSaveFileName()
42-
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
43-
44-
backend_version = "0.9.1"
23+
from qt4_compat import QtCore, QtGui, _getSaveFileName, __version__
24+
25+
backend_version = __version__
4526
def fn_name(): return sys._getframe(1).f_code.co_name
4627

4728
DEBUG = False
@@ -292,22 +273,6 @@ def idle_draw(*args):
292273
self._idle = True
293274
if d: QtCore.QTimer.singleShot(0, idle_draw)
294275

295-
296-
# XXX Hackish fix: There's a bug in PyQt. See this thread for details:
297-
# http://old.nabble.com/Qt4-backend:-critical-bug-with-PyQt4-v4.6%2B-td26205716.html
298-
# Once a release of Qt/PyQt is available without the bug, the version check
299-
# below can be tightened further to only be applied in the necessary versions.
300-
if QtCore.PYQT_VERSION_STR.startswith('4.6'):
301-
class FigureWindow(QtGui.QMainWindow):
302-
def __init__(self):
303-
super(FigureWindow, self).__init__()
304-
def closeEvent(self, event):
305-
super(FigureWindow, self).closeEvent(event)
306-
self.emit(QtCore.SIGNAL('destroyed()'))
307-
else:
308-
FigureWindow = QtGui.QMainWindow
309-
# /end pyqt hackish bugfix
310-
311276
class FigureManagerQT( FigureManagerBase ):
312277
"""
313278
Public attributes
@@ -322,7 +287,7 @@ def __init__( self, canvas, num ):
322287
if DEBUG: print 'FigureManagerQT.%s' % fn_name()
323288
FigureManagerBase.__init__( self, canvas, num )
324289
self.canvas = canvas
325-
self.window = FigureWindow()
290+
self.window = QtGui.QMainWindow()
326291
self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
327292

328293
self.window.setWindowTitle("Figure %d" % num)
@@ -341,7 +306,7 @@ def __init__( self, canvas, num ):
341306
if self.toolbar is not None:
342307
self.window.addToolBar(self.toolbar)
343308
QtCore.QObject.connect(self.toolbar, QtCore.SIGNAL("message"),
344-
self.window.statusBar().showMessage)
309+
self._show_message)
345310
tbs_height = self.toolbar.sizeHint().height()
346311
else:
347312
tbs_height = 0
@@ -366,6 +331,11 @@ def notify_axes_change( fig ):
366331
self.toolbar.update()
367332
self.canvas.figure.add_axobserver( notify_axes_change )
368333

334+
@QtCore.Slot()
335+
def _show_message(self,s):
336+
# Fixes a PySide segfault.
337+
self.window.statusBar().showMessage(s)
338+
369339
def _widgetclosed( self ):
370340
if self.window._destroying: return
371341
self.window._destroying = True

lib/matplotlib/backends/backend_qt4agg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def paintEvent( self, e ):
9191
else:
9292
stringBuffer = self.renderer._renderer.tostring_argb()
9393

94-
qImage = QtGui.QImage(stringBuffer, self.renderer.width,
94+
qImage = QtGui.QImage(stringBuffer, self.renderer.width,
9595
self.renderer.height,
9696
QtGui.QImage.Format_ARGB32)
9797
p = QtGui.QPainter(self)

lib/matplotlib/backends/qt4_compat.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
""" A Qt API selector that can be used to switch between PyQt and PySide.
2+
"""
3+
4+
import os
5+
6+
# Available APIs.
7+
QT_API_PYQT = 'pyqt'
8+
QT_API_PYSIDE = 'pyside'
9+
10+
# Select PyQt4 or PySide using an environment variable, in the same way IPython does.
11+
# IPython is using PyQt as default (for now) so we will too.
12+
QT_API = os.environ.get('QT_API', QT_API_PYQT)
13+
14+
if QT_API == QT_API_PYQT:
15+
try:
16+
from PyQt4 import QtCore, QtGui
17+
except ImportError:
18+
raise ImportError("Qt4 backend requires that PyQt4 is installed.")
19+
# Alias PyQt-specific functions for PySide compatibility.
20+
try:
21+
QtCore.Slot = QtCore.pyqtSlot
22+
except AttributeError:
23+
QtCore.Slot = pyqtSignature # Not a perfect match but
24+
# works in simple cases
25+
QtCore.Property = QtCore.pyqtProperty
26+
__version__ = QtCore.PYQT_VERSION_STR
27+
import sip
28+
try :
29+
if sip.getapi("QString") > 1 :
30+
# Use new getSaveFileNameAndFilter()
31+
_getSaveFileName = lambda self, msg, start, filters, \
32+
selectedFilter : \
33+
QtGui.QFileDialog.getSaveFileNameAndFilter( \
34+
self, msg, start, filters, selectedFilter)[0]
35+
else :
36+
# Use old getSaveFileName()
37+
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
38+
except (AttributeError, KeyError) :
39+
# call to getapi() can fail in older versions of sip
40+
# Use the old getSaveFileName()
41+
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
42+
43+
elif QT_API == QT_API_PYSIDE:
44+
try:
45+
from PySide import QtCore, QtGui, __version__, __version_info__
46+
except ImportError:
47+
raise ImportError("Qt4 backend requires that PySide is installed.")
48+
if __version_info__ < (1,0,3):
49+
raise ImportError("Matplotlib backend_qt4 and backend_qt4agg require PySide >=1.0.3")
50+
51+
# Alias PySide-specific function for PyQt compatibilty
52+
QtCore.pyqtProperty = QtCore.Property
53+
QtCore.pyqtSignature = QtCore.Slot # Not a perfect match but
54+
# works in simple cases
55+
56+
_getSaveFileName = lambda self, msg, start, filters, selectedFilter : \
57+
QtGui.QFileDialog.getSaveFileName(self, \
58+
msg, start, filters, selectedFilter)[0]
59+
else:
60+
raise RuntimeError('Invalid Qt API %r, valid values are: %r or %r' %
61+
(QT_API, QT_API_PYQT, QT_API_PYSIDE))

lib/matplotlib/backends/qt4_editor/figureoptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
import os.path as osp
1010

1111
import matplotlib.backends.qt4_editor.formlayout as formlayout
12-
from PyQt4.QtGui import QIcon
12+
from matplotlib.backends.qt4_compat import QtGui
1313

1414
def get_icon(name):
1515
import matplotlib
1616
basedir = osp.join(matplotlib.rcParams['datapath'], 'images')
17-
return QIcon(osp.join(basedir, name))
17+
return QtGui.QIcon(osp.join(basedir, name))
1818

1919
LINESTYLES = {
2020
'-': 'Solid',

0 commit comments

Comments
 (0)