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

Skip to content

Commit 7a96a9f

Browse files
authored
Merge pull request #16767 from meeseeksmachine/auto-backport-of-pr-15685-on-v3.2.x
Backport PR #15685 on branch v3.2.x (Avoid a RuntimeError at animation shutdown with PySide2.)
2 parents aa8e55e + 6975ba8 commit 7a96a9f

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

lib/matplotlib/backends/backend_qt5.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
from matplotlib.backend_managers import ToolManager
1818

1919
from .qt_compat import (
20-
QtCore, QtGui, QtWidgets, _getSaveFileName, is_pyqt5, __version__, QT_API)
20+
QtCore, QtGui, QtWidgets, _isdeleted, _getSaveFileName,
21+
is_pyqt5, __version__, QT_API)
2122

2223
backend_version = __version__
2324

@@ -200,6 +201,12 @@ def __init__(self, *args, **kwargs):
200201
self._timer.timeout.connect(self._on_timer)
201202
self._timer_set_interval()
202203

204+
def __del__(self):
205+
# The check for deletedness is needed to avoid an error at animation
206+
# shutdown with PySide2.
207+
if not _isdeleted(self._timer):
208+
self._timer_stop()
209+
203210
def _timer_set_single_shot(self):
204211
self._timer.setSingleShot(self._single)
205212

lib/matplotlib/backends/qt_compat.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,21 @@
6363

6464

6565
def _setup_pyqt5():
66-
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
66+
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, \
67+
_isdeleted, _getSaveFileName
6768

6869
if QT_API == QT_API_PYQT5:
6970
from PyQt5 import QtCore, QtGui, QtWidgets
71+
import sip
7072
__version__ = QtCore.PYQT_VERSION_STR
7173
QtCore.Signal = QtCore.pyqtSignal
7274
QtCore.Slot = QtCore.pyqtSlot
7375
QtCore.Property = QtCore.pyqtProperty
76+
_isdeleted = sip.isdeleted
7477
elif QT_API == QT_API_PYSIDE2:
7578
from PySide2 import QtCore, QtGui, QtWidgets, __version__
79+
import shiboken2
80+
def _isdeleted(obj): return not shiboken2.isValid(obj)
7681
else:
7782
raise ValueError("Unexpected value for the 'backend.qt5' rcparam")
7883
_getSaveFileName = QtWidgets.QFileDialog.getSaveFileName
@@ -82,7 +87,8 @@ def is_pyqt5():
8287

8388

8489
def _setup_pyqt4():
85-
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
90+
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, \
91+
_isdeleted, _getSaveFileName
8692

8793
def _setup_pyqt4_internal(api):
8894
global QtCore, QtGui, QtWidgets, \
@@ -102,6 +108,7 @@ def _setup_pyqt4_internal(api):
102108
except ValueError:
103109
pass
104110
from PyQt4 import QtCore, QtGui
111+
import sip # Always succeeds *after* importing PyQt4.
105112
__version__ = QtCore.PYQT_VERSION_STR
106113
# PyQt 4.6 introduced getSaveFileNameAndFilter:
107114
# https://riverbankcomputing.com/news/pyqt-46
@@ -110,16 +117,19 @@ def _setup_pyqt4_internal(api):
110117
QtCore.Signal = QtCore.pyqtSignal
111118
QtCore.Slot = QtCore.pyqtSlot
112119
QtCore.Property = QtCore.pyqtProperty
120+
_isdeleted = sip.isdeleted
113121
_getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter
114122

115123
if QT_API == QT_API_PYQTv2:
116124
_setup_pyqt4_internal(api=2)
117125
elif QT_API == QT_API_PYSIDE:
118126
from PySide import QtCore, QtGui, __version__, __version_info__
127+
import shiboken
119128
# PySide 1.0.3 fixed the following:
120129
# https://srinikom.github.io/pyside-bz-archive/809.html
121130
if __version_info__ < (1, 0, 3):
122131
raise ImportError("PySide<1.0.3 is not supported")
132+
def _isdeleted(obj): return not shiboken.isValid(obj)
123133
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
124134
elif QT_API == QT_API_PYQT:
125135
_setup_pyqt4_internal(api=1)

0 commit comments

Comments
 (0)