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

Skip to content

Commit f007419

Browse files
committed
Cooperative __init__ for Qt4 canvas.
1 parent 225a4a0 commit f007419

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

lib/matplotlib/backends/backend_qt4.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,6 @@
2828

2929
class FigureCanvasQT(FigureCanvasQT5):
3030

31-
def __init__(self, figure):
32-
if DEBUG:
33-
print('FigureCanvasQt qt4: ', figure)
34-
_create_qApp()
35-
36-
# Note different super-calling style to backend_qt5
37-
QtWidgets.QWidget.__init__(self)
38-
FigureCanvasBase.__init__(self, figure)
39-
self.figure = figure
40-
self.setMouseTracking(True)
41-
self._idle = True
42-
w, h = self.get_width_height()
43-
self.resize(w, h)
44-
45-
# Key auto-repeat enabled by default
46-
self._keyautorepeat = True
47-
4831
def wheelEvent(self, event):
4932
x = event.x()
5033
# flipy so y=0 is bottom of canvas

lib/matplotlib/backends/backend_qt5.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
unicode_literals)
33
import six
44

5+
import functools
56
import os
67
import re
78
import signal
@@ -18,8 +19,8 @@
1819
from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
1920
from matplotlib.figure import Figure
2021

21-
from .qt_compat import (QtCore, QtGui, QtWidgets, _getSaveFileName,
22-
__version__, is_pyqt5)
22+
from .qt_compat import (
23+
QtCore, QtGui, QtWidgets, _getSaveFileName, is_pyqt5, __version__, QT_API)
2324

2425
backend_version = __version__
2526

@@ -132,6 +133,51 @@ def _create_qApp():
132133
pass
133134

134135

136+
def _allow_super_init(__init__):
137+
"""
138+
Decorator for ``__init__`` to allow ``super().__init__`` on PyQt4/PySide2.
139+
"""
140+
141+
if QT_API == "PyQt5":
142+
143+
return __init__
144+
145+
else:
146+
# To work around lack of cooperative inheritance in PyQt4, PySide,
147+
# and PySide2, when calling FigureCanvasQT.__init__, we temporarily
148+
# patch QWidget.__init__ by a cooperative version, that first calls
149+
# QWidget.__init__ with no additional arguments, and then finds the
150+
# next class in the MRO with an __init__ that does support cooperative
151+
# inheritance (i.e., not defined by the PyQt4, PySide, PySide2, sip
152+
# or Shiboken packages), and manually call its `__init__`, once again
153+
# passing the additional arguments.
154+
155+
qwidget_init = QtWidgets.QWidget.__init__
156+
157+
def cooperative_qwidget_init(self, *args, **kwargs):
158+
qwidget_init(self)
159+
mro = type(self).__mro__
160+
next_coop_init = next(
161+
cls for cls in mro[mro.index(QtWidgets.QWidget) + 1:]
162+
if cls.__module__.split(".")[0] not in [
163+
"PyQt4", "sip", "PySide", "PySide2", "Shiboken"])
164+
next_coop_init.__init__(self, *args, **kwargs)
165+
166+
@functools.wraps(__init__)
167+
def wrapper(self, **kwargs):
168+
try:
169+
QtWidgets.QWidget.__init__ = cooperative_qwidget_init
170+
__init__(self, **kwargs)
171+
finally:
172+
try:
173+
# Restore __init__ to sip.simplewrapper.__init__.
174+
del QtWidgets.QWidget.__init__
175+
except AttributeError:
176+
pass
177+
178+
return wrapper
179+
180+
135181
class TimerQT(TimerBase):
136182
'''
137183
Subclass of :class:`backend_bases.TimerBase` that uses Qt timer events.
@@ -186,23 +232,20 @@ def _update_figure_dpi(self):
186232
dpi = self._dpi_ratio * self.figure._original_dpi
187233
self.figure._set_dpi(dpi, forward=False)
188234

235+
@_allow_super_init
189236
def __init__(self, figure):
190237
_create_qApp()
191238
figure._original_dpi = figure.dpi
192239

193-
# NB: Using super for this call to avoid a TypeError:
194-
# __init__() takes exactly 2 arguments (1 given) on QWidget
195-
# PyQt5
196-
# The need for this change is documented here
197-
# http://pyqt.sourceforge.net/Docs/PyQt5/pyqt4_differences.html#cooperative-multi-inheritance
198240
super(FigureCanvasQT, self).__init__(figure=figure)
241+
199242
self.figure = figure
200243
self._update_figure_dpi()
201244

202-
self.setMouseTracking(True)
203245
w, h = self.get_width_height()
204246
self.resize(w, h)
205247

248+
self.setMouseTracking(True)
206249
# Key auto-repeat enabled by default
207250
self._keyautorepeat = True
208251

0 commit comments

Comments
 (0)