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

Skip to content

Commit fa0c1be

Browse files
committed
Various backend cleanups.
Split out from the qt5cairo and wxcairo PRs. - GTK3: is_drawable is the same as mapped & visible (https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-is-drawable) - Synchronous draw appears unnecessary on GTK3 based on tests (probably was only needed in early animation code). - Most of the Wx printout code has been removed in 84ffb60; this PR just deprecates some remnants of it. MenuButtonWx is likewise unused since the removal of "classic" toolbars in 4243470; this PR deprecates it. - Don't initialize the wx statusbar to "None" (which just looks strange) -- other backends just start with an empty status text. - _convert_agg_to_wx_image is unused; _WX28_clipped_agg_as_bitmap can reasonably be inlined into _convert_agg_to_wx_bitmap. - Simplify toolkit mocking in the docs. In particular pycairo is Py3-compatible only since 1.11.0 so the version_check is unneeded.
1 parent aae55fc commit fa0c1be

File tree

8 files changed

+48
-119
lines changed

8 files changed

+48
-119
lines changed

doc/api/backend_wxagg_api.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
:mod:`matplotlib.backends.backend_wxagg`
33
========================================
44

5-
.. automodule:: matplotlib.backends.backend_wxagg
6-
:members:
7-
:undoc-members:
8-
:show-inheritance:
5+
**NOTE** Not included, to avoid adding a dependency to building the docs.
6+
7+
.. .. automodule:: matplotlib.backends.backend_wxagg
8+
.. :members:
9+
.. :undoc-members:
10+
.. :show-inheritance:

doc/sphinxext/mock_gui_toolkits.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,10 @@ def getapi(*args):
108108
return 1
109109

110110

111-
class MyWX(MagicMock):
112-
class Panel(object):
113-
pass
114-
115-
class ToolBar(object):
116-
pass
117-
118-
class Frame(object):
119-
pass
120-
121-
122111
def setup(app):
123112
sys.modules.update(
124113
cairocffi=MyCairoCffi(),
125114
PyQt4=MyPyQt4(),
126115
sip=MySip(),
127-
wx=MyWX(),
128116
)
129117
return {'parallel_read_safe': True, 'parallel_write_safe': True}

lib/matplotlib/backends/backend_agg.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -409,21 +409,13 @@ def restore_region(self, region, bbox=None, xy=None):
409409
return renderer.restore_region(region, bbox, xy)
410410

411411
def draw(self):
412-
"""
413-
Draw the figure using the renderer
414-
"""
412+
"""Draw the figure using the renderer."""
415413
self.renderer = self.get_renderer(cleared=True)
416-
# acquire a lock on the shared font cache
417-
RendererAgg.lock.acquire()
418-
419-
toolbar = self.toolbar
420-
try:
414+
with RendererAgg.lock:
421415
self.figure.draw(self.renderer)
422-
# A GUI class may be need to update a window using this draw, so
423-
# don't forget to call the superclass.
416+
# A GUI class may be need to update a window using this draw,
417+
# so don't forget to call the superclass.
424418
super().draw()
425-
finally:
426-
RendererAgg.lock.release()
427419

428420
def get_renderer(self, cleared=False):
429421
l, b, w, h = self.figure.bbox.bounds

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,8 @@ def on_draw_event(self, widget, ctx):
278278
pass
279279

280280
def draw(self):
281-
if self.get_visible() and self.get_mapped():
281+
if self.is_drawable():
282282
self.queue_draw()
283-
# do a synchronous draw (its less efficient than an async draw,
284-
# but is required if/when animation is used)
285-
self.get_property("window").process_updates(False)
286283

287284
def draw_idle(self):
288285
if self._idle_draw_id != 0:

lib/matplotlib/backends/backend_gtk3cairo.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from . import backend_cairo, backend_gtk3
22
from ._gtk3_compat import gi
33
from .backend_gtk3 import Gtk, _BackendGTK3
4+
from matplotlib import cbook
45
from matplotlib.backend_bases import cursors
56

67

@@ -36,11 +37,11 @@ def on_draw_event(self, widget, ctx):
3637
return False # finish event propagation?
3738

3839

40+
@cbook.deprecated("3.0", "backend_gtk3.FigureManagerGTK3")
3941
class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
4042
pass
4143

4244

4345
@_BackendGTK3.export
4446
class _BackendGTK3Cairo(_BackendGTK3):
4547
FigureCanvas = FigureCanvasGTK3Cairo
46-
FigureManager = FigureManagerGTK3Cairo

lib/matplotlib/backends/backend_qt5agg.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Render to qt from agg
2+
Render to qt from agg.
33
"""
44

55
import ctypes
@@ -30,8 +30,8 @@ def paintEvent(self, e):
3030
return
3131
self._draw_idle() # Only does something if a draw is pending.
3232

33-
# if the canvas does not have a renderer, then give up and wait for
34-
# FigureCanvasAgg.draw(self) to be called
33+
# If the canvas does not have a renderer, then give up and wait for
34+
# FigureCanvasAgg.draw(self) to be called.
3535
if not hasattr(self, 'renderer'):
3636
return
3737

lib/matplotlib/backends/backend_wx.py

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
NavigationToolbar2, RendererBase, TimerBase, cursors)
2020
from matplotlib.backend_bases import _has_pil
2121

22+
from matplotlib import cbook, rcParams, backend_tools
2223
from matplotlib._pylab_helpers import Gcf
2324
from matplotlib.cbook import is_writable_file_like, warn_deprecated
2425
from matplotlib.figure import Figure
2526
from matplotlib.path import Path
2627
from matplotlib.transforms import Affine2D
2728
from matplotlib.widgets import SubplotTool
28-
from matplotlib import cbook, rcParams, backend_tools
2929

3030
import wx
3131

@@ -35,30 +35,25 @@
3535
# traceback is performed, and pdb activated, for all uncaught exceptions in
3636
# this case
3737
_DEBUG = 5
38-
if _DEBUG < 5:
39-
import traceback
40-
import pdb
4138
_DEBUG_lvls = {1: 'Low ', 2: 'Med ', 3: 'High', 4: 'Error'}
4239

4340

4441
def DEBUG_MSG(string, lvl=3, o=None):
4542
if lvl >= _DEBUG:
46-
cls = o.__class__
47-
# Jeremy, often times the commented line won't print but the
48-
# one below does. I think WX is redefining stderr, damned
49-
# beast
50-
# print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls),
51-
# file=sys.stderr)
52-
print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls))
43+
print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, type(o)))
5344

5445

46+
@cbook.deprecated("3.0")
5547
def debug_on_error(type, value, tb):
5648
"""Code due to Thomas Heller - published in Python Cookbook (O'Reilley)"""
49+
import pdb
50+
import traceback
5751
traceback.print_exception(type, value, tb)
5852
print()
59-
pdb.pm() # jdh uncomment
53+
pdb.pm()
6054

6155

56+
@cbook.deprecated("3.0")
6257
class fake_stderr(object):
6358
"""
6459
Wx does strange things with stderr, as it makes the assumption that
@@ -93,6 +88,7 @@ def error_msg_wx(msg, parent=None):
9388
return None
9489

9590

91+
@cbook.deprecated("3.0")
9692
def raise_msg_to_str(msg):
9793
"""msg is a return arg from a raise. Join with new lines."""
9894
if not isinstance(msg, str):
@@ -1104,22 +1100,16 @@ def _print_image(self, filename, filetype, *args, **kwargs):
11041100
image = self.bitmap.ConvertToImage()
11051101
image.SetOption(wx.IMAGE_OPTION_QUALITY, str(jpeg_quality))
11061102

1107-
# Now that we have rendered into the bitmap, save it
1108-
# to the appropriate file type and clean up
1103+
# Now that we have rendered into the bitmap, save it to the appropriate
1104+
# file type and clean up.
11091105
if isinstance(filename, str):
11101106
if not image.SaveFile(filename, filetype):
1111-
DEBUG_MSG('print_figure() file save error', 4, self)
1112-
raise RuntimeError(
1113-
'Could not save figure to %s\n' %
1114-
(filename))
1107+
raise RuntimeError('Could not save figure to %s' % filename)
11151108
elif is_writable_file_like(filename):
11161109
if not isinstance(image, wx.Image):
11171110
image = image.ConvertToImage()
11181111
if not image.SaveStream(filename, filetype):
1119-
DEBUG_MSG('print_figure() file save error', 4, self)
1120-
raise RuntimeError(
1121-
'Could not save figure to %s\n' %
1122-
(filename))
1112+
raise RuntimeError('Could not save figure to %s' % filename)
11231113

11241114
# Restore everything to normal
11251115
self.bitmap = origBitmap
@@ -1286,11 +1276,7 @@ def resize(self, width, height):
12861276
self.canvas.SetInitialSize(wx.Size(width, height))
12871277
self.window.GetSizer().Fit(self.window)
12881278

1289-
# Identifiers for toolbar controls - images_wx contains bitmaps for the images
1290-
# used in the controls. wxWindows does not provide any stock images, so I've
1291-
# 'stolen' those from GTK2, and transformed them into the appropriate format.
1292-
# import images_wx
1293-
1279+
# Identifiers for toolbar controls.
12941280

12951281
_NTB_AXISMENU = wx.NewId()
12961282
_NTB_AXISMENU_BUTTON = wx.NewId()
@@ -1302,7 +1288,6 @@ def resize(self, width, height):
13021288
_NTB_Y_PAN_DOWN = wx.NewId()
13031289
_NTB_Y_ZOOMIN = wx.NewId()
13041290
_NTB_Y_ZOOMOUT = wx.NewId()
1305-
# _NTB_SUBPLOT =wx.NewId()
13061291
_NTB_SAVE = wx.NewId()
13071292
_NTB_CLOSE = wx.NewId()
13081293

@@ -1326,6 +1311,7 @@ def _load_bitmap(filename):
13261311
return bmp
13271312

13281313

1314+
@cbook.deprecated("3.0")
13291315
class MenuButtonWx(wx.Button):
13301316
"""
13311317
wxPython does not permit a menu to be incorporated directly into a toolbar.
@@ -1403,7 +1389,7 @@ def updateAxes(self, maxAxis):
14031389
"""Ensures that there are entries for max_axis axes in the menu
14041390
(selected by default)."""
14051391
if maxAxis > len(self._axisId):
1406-
for i in range(len(self._axisId) + 1, maxAxis + 1, 1):
1392+
for i in range(len(self._axisId) + 1, maxAxis + 1):
14071393
menuId = wx.NewId()
14081394
self._axisId.append(menuId)
14091395
self._menu.Append(menuId, "Axis %d" % i,
@@ -1676,16 +1662,10 @@ class StatusBarWx(wx.StatusBar):
16761662
def __init__(self, parent):
16771663
wx.StatusBar.__init__(self, parent, -1)
16781664
self.SetFieldsCount(2)
1679-
self.SetStatusText("None", 1)
1680-
# self.SetStatusText("Measurement: None", 2)
1681-
# self.Reposition()
16821665

16831666
def set_function(self, string):
16841667
self.SetStatusText("%s" % string, 1)
16851668

1686-
# def set_measurement(self, string):
1687-
# self.SetStatusText("Measurement: %s" % string, 2)
1688-
16891669

16901670
# tools for matplotlib.backend_managers.ToolManager:
16911671
# for now only SaveFigure, SetCursor and Rubberband are implemented
@@ -1844,6 +1824,7 @@ def trigger(self, *args, **kwargs):
18441824

18451825
# < Additions for printing support: Matt Newville
18461826

1827+
@cbook.deprecated("3.0")
18471828
class PrintoutWx(wx.Printout):
18481829
"""
18491830
Simple wrapper around wx Printout class -- all the real work
@@ -1925,7 +1906,6 @@ def OnPrintPage(self, page):
19251906
self.canvas.figure.dpi = fig_dpi
19261907
self.canvas.draw()
19271908
return True
1928-
# >
19291909

19301910

19311911
@_Backend.export

lib/matplotlib/backends/backend_wxagg.py

Lines changed: 16 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,11 @@ def blit(self, bbox=None):
6161
srcDC.SelectObject(wx.NullBitmap)
6262
self.gui_repaint()
6363

64-
filetypes = FigureCanvasAgg.filetypes
65-
66-
67-
# agg/wxPython image conversion functions (wxPython >= 2.8)
68-
69-
def _convert_agg_to_wx_image(agg, bbox):
70-
"""
71-
Convert the region of the agg buffer bounded by bbox to a wx.Image. If
72-
bbox is None, the entire buffer is converted.
73-
74-
Note: agg must be a backend_agg.RendererAgg instance.
75-
"""
76-
if bbox is None:
77-
# agg => rgb -> image
78-
image = wx.Image(int(agg.width), int(agg.height))
79-
image.SetData(agg.tostring_rgb())
80-
return image
81-
else:
82-
# agg => rgba buffer -> bitmap => clipped bitmap => image
83-
return wx.ImageFromBitmap(_WX28_clipped_agg_as_bitmap(agg, bbox))
84-
8564

8665
def _convert_agg_to_wx_bitmap(agg, bbox):
8766
"""
8867
Convert the region of the agg buffer bounded by bbox to a wx.Bitmap. If
8968
bbox is None, the entire buffer is converted.
90-
9169
Note: agg must be a backend_agg.RendererAgg instance.
9270
"""
9371
if bbox is None:
@@ -96,36 +74,27 @@ def _convert_agg_to_wx_bitmap(agg, bbox):
9674
agg.buffer_rgba())
9775
else:
9876
# agg => rgba buffer -> bitmap => clipped bitmap
99-
return _WX28_clipped_agg_as_bitmap(agg, bbox)
77+
l, b, width, height = bbox.bounds
78+
r = l + width
79+
t = b + height
10080

81+
srcBmp = wx.Bitmap.FromBufferRGBA(int(agg.width), int(agg.height),
82+
agg.buffer_rgba())
83+
srcDC = wx.MemoryDC()
84+
srcDC.SelectObject(srcBmp)
10185

102-
def _WX28_clipped_agg_as_bitmap(agg, bbox):
103-
"""
104-
Convert the region of a the agg buffer bounded by bbox to a wx.Bitmap.
105-
106-
Note: agg must be a backend_agg.RendererAgg instance.
107-
"""
108-
l, b, width, height = bbox.bounds
109-
r = l + width
110-
t = b + height
111-
112-
srcBmp = wx.Bitmap.FromBufferRGBA(int(agg.width), int(agg.height),
113-
agg.buffer_rgba())
114-
srcDC = wx.MemoryDC()
115-
srcDC.SelectObject(srcBmp)
116-
117-
destBmp = wx.Bitmap(int(width), int(height))
118-
destDC = wx.MemoryDC()
119-
destDC.SelectObject(destBmp)
86+
destBmp = wx.Bitmap(int(width), int(height))
87+
destDC = wx.MemoryDC()
88+
destDC.SelectObject(destBmp)
12089

121-
x = int(l)
122-
y = int(int(agg.height) - t)
123-
destDC.Blit(0, 0, int(width), int(height), srcDC, x, y)
90+
x = int(l)
91+
y = int(int(agg.height) - t)
92+
destDC.Blit(0, 0, int(width), int(height), srcDC, x, y)
12493

125-
srcDC.SelectObject(wx.NullBitmap)
126-
destDC.SelectObject(wx.NullBitmap)
94+
srcDC.SelectObject(wx.NullBitmap)
95+
destDC.SelectObject(wx.NullBitmap)
12796

128-
return destBmp
97+
return destBmp
12998

13099

131100
@_BackendWx.export

0 commit comments

Comments
 (0)