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

Skip to content

Commit d762d6d

Browse files
authored
Merge pull request #11520 from anntzer/getcurrenteventloop
Add private API retrieving the current event loop and backend GUI info.
2 parents d9d7ff1 + 93ebee6 commit d762d6d

File tree

9 files changed

+78
-1
lines changed

9 files changed

+78
-1
lines changed

doc/api/next_api_changes/2018-06-27-AL.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,10 @@ Changes to backend loading
44
Failure to load backend modules (``macosx`` on non-framework builds and
55
``gtk3`` when running headless) now raises `ImportError` (instead of
66
`RuntimeError` and `TypeError`, respectively.
7+
8+
Third-party backends that integrate with an interactive framework are now
9+
encouraged to define the ``required_interactive_framework`` global value to one
10+
of the following values: "qt5", "qt4", "gtk3", "wx", "tk", or "macosx". This
11+
information will be used to determine whether it is possible to switch from a
12+
backend to another (specifically, whether they use the same interactive
13+
framework).

lib/matplotlib/backends/__init__.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import importlib
22
import logging
3+
import os
4+
import sys
35
import traceback
46

57
import matplotlib
@@ -14,6 +16,54 @@
1416
if not line.startswith(' File "<frozen importlib._bootstrap'))
1517

1618

19+
def _get_running_interactive_framework():
20+
"""
21+
Return the interactive framework whose event loop is currently running, if
22+
any, or "headless" if no event loop can be started, or None.
23+
24+
Returns
25+
-------
26+
Optional[str]
27+
One of the following values: "qt5", "qt4", "gtk3", "wx", "tk",
28+
"macosx", "headless", ``None``.
29+
"""
30+
QtWidgets = (sys.modules.get("PyQt5.QtWidgets")
31+
or sys.modules.get("PySide2.QtWidgets"))
32+
if QtWidgets and QtWidgets.QApplication.instance():
33+
return "qt5"
34+
QtGui = (sys.modules.get("PyQt4.QtGui")
35+
or sys.modules.get("PySide.QtGui"))
36+
if QtGui and QtGui.QApplication.instance():
37+
return "qt4"
38+
Gtk = (sys.modules.get("gi.repository.Gtk")
39+
or sys.modules.get("pgi.repository.Gtk"))
40+
if Gtk and Gtk.main_level():
41+
return "gtk3"
42+
wx = sys.modules.get("wx")
43+
if wx and wx.GetApp():
44+
return "wx"
45+
tkinter = sys.modules.get("tkinter")
46+
if tkinter:
47+
for frame in sys._current_frames().values():
48+
while frame:
49+
if frame.f_code == tkinter.mainloop.__code__:
50+
return "tk"
51+
frame = frame.f_back
52+
try:
53+
from matplotlib.backends import _macosx
54+
except ImportError:
55+
pass
56+
else:
57+
# Note that the NSApp event loop is also running when a non-native
58+
# toolkit (e.g. Qt5) is active, but in that case we want to report the
59+
# other toolkit; thus, this check comes after the other toolkits.
60+
if _macosx.event_loop_is_running():
61+
return "macosx"
62+
if sys.platform.startswith("linux") and not os.environ.get("DISPLAY"):
63+
return "headless"
64+
return None
65+
66+
1767
def pylab_setup(name=None):
1868
"""
1969
Return new_figure_manager, draw_if_interactive and show for pyplot.

lib/matplotlib/backends/_backend_tk.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,7 @@ def trigger(self, *args):
995995

996996
@_Backend.export
997997
class _BackendTk(_Backend):
998+
required_interactive_framework = "tk"
998999
FigureManager = FigureManagerTk
9991000

10001001
@classmethod

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ def error_msg_gtk(msg, parent=None):
976976

977977
@_Backend.export
978978
class _BackendGTK3(_Backend):
979+
required_interactive_framework = "gtk3"
979980
FigureCanvas = FigureCanvasGTK3
980981
FigureManager = FigureManagerGTK3
981982

lib/matplotlib/backends/backend_macosx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def set_message(self, message):
185185

186186
@_Backend.export
187187
class _BackendMac(_Backend):
188+
required_interactive_framework = "macosx"
188189
FigureCanvas = FigureCanvasMac
189190
FigureManager = FigureManagerMac
190191

lib/matplotlib/backends/backend_qt4.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
@_BackendQT5.export
99
class _BackendQT4(_BackendQT5):
10-
pass
10+
required_interactive_framework = "qt4"

lib/matplotlib/backends/backend_qt5.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,7 @@ def exception_handler(type, value, tb):
11081108

11091109
@_Backend.export
11101110
class _BackendQT5(_Backend):
1111+
required_interactive_framework = "qt5"
11111112
FigureCanvas = FigureCanvasQT
11121113
FigureManager = FigureManagerQT
11131114

lib/matplotlib/backends/backend_wx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,7 @@ def OnPrintPage(self, page):
19301930

19311931
@_Backend.export
19321932
class _BackendWx(_Backend):
1933+
required_interactive_framework = "wx"
19331934
FigureCanvas = FigureCanvasWx
19341935
FigureManager = FigureManagerWx
19351936
_frame_class = FigureFrameWx

src/_macosx.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,16 @@ - (int)index
27892789
}
27902790
@end
27912791

2792+
static PyObject*
2793+
event_loop_is_running(PyObject* self)
2794+
{
2795+
if ([NSApp isRunning]) {
2796+
Py_RETURN_TRUE;
2797+
} else {
2798+
Py_RETURN_FALSE;
2799+
}
2800+
}
2801+
27922802
static PyObject*
27932803
show(PyObject* self)
27942804
{
@@ -3038,6 +3048,11 @@ static bool verify_framework(void)
30383048
}
30393049

30403050
static struct PyMethodDef methods[] = {
3051+
{"event_loop_is_running",
3052+
(PyCFunction)event_loop_is_running,
3053+
METH_NOARGS,
3054+
"Return whether the NSApp main event loop is currently running."
3055+
},
30413056
{"show",
30423057
(PyCFunction)show,
30433058
METH_NOARGS,

0 commit comments

Comments
 (0)