.. _sphx_glr_gallery_widgets_menu.py: ==== Menu ==== .. image:: /gallery/widgets/images/sphx_glr_menu_001.png :align: center .. rst-class:: sphx-glr-script-out Out:: 100 371 91 29 100 342 91 29 100 313 91 29 100 284 91 29 100 255 91 29 | .. code-block:: python from __future__ import division, print_function import numpy as np import matplotlib import matplotlib.colors as colors import matplotlib.patches as patches import matplotlib.mathtext as mathtext import matplotlib.pyplot as plt import matplotlib.artist as artist import matplotlib.image as image class ItemProperties(object): def __init__(self, fontsize=14, labelcolor='black', bgcolor='yellow', alpha=1.0): self.fontsize = fontsize self.labelcolor = labelcolor self.bgcolor = bgcolor self.alpha = alpha self.labelcolor_rgb = colors.to_rgba(labelcolor)[:3] self.bgcolor_rgb = colors.to_rgba(bgcolor)[:3] class MenuItem(artist.Artist): parser = mathtext.MathTextParser("Bitmap") padx = 5 pady = 5 def __init__(self, fig, labelstr, props=None, hoverprops=None, on_select=None): artist.Artist.__init__(self) self.set_figure(fig) self.labelstr = labelstr if props is None: props = ItemProperties() if hoverprops is None: hoverprops = ItemProperties() self.props = props self.hoverprops = hoverprops self.on_select = on_select x, self.depth = self.parser.to_mask( labelstr, fontsize=props.fontsize, dpi=fig.dpi) if props.fontsize != hoverprops.fontsize: raise NotImplementedError( 'support for different font sizes not implemented') self.labelwidth = x.shape[1] self.labelheight = x.shape[0] self.labelArray = np.zeros((x.shape[0], x.shape[1], 4)) self.labelArray[:, :, -1] = x/255. self.label = image.FigureImage(fig, origin='upper') self.label.set_array(self.labelArray) # we'll update these later self.rect = patches.Rectangle((0, 0), 1, 1) self.set_hover_props(False) fig.canvas.mpl_connect('button_release_event', self.check_select) def check_select(self, event): over, junk = self.rect.contains(event) if not over: return if self.on_select is not None: self.on_select(self) def set_extent(self, x, y, w, h): print(x, y, w, h) self.rect.set_x(x) self.rect.set_y(y) self.rect.set_width(w) self.rect.set_height(h) self.label.ox = x + self.padx self.label.oy = y - self.depth + self.pady/2. self.rect._update_patch_transform() self.hover = False def draw(self, renderer): self.rect.draw(renderer) self.label.draw(renderer) def set_hover_props(self, b): if b: props = self.hoverprops else: props = self.props r, g, b = props.labelcolor_rgb self.labelArray[:, :, 0] = r self.labelArray[:, :, 1] = g self.labelArray[:, :, 2] = b self.label.set_array(self.labelArray) self.rect.set(facecolor=props.bgcolor, alpha=props.alpha) def set_hover(self, event): 'check the hover status of event and return true if status is changed' b, junk = self.rect.contains(event) changed = (b != self.hover) if changed: self.set_hover_props(b) self.hover = b return changed class Menu(object): def __init__(self, fig, menuitems): self.figure = fig fig.suppressComposite = True self.menuitems = menuitems self.numitems = len(menuitems) maxw = max(item.labelwidth for item in menuitems) maxh = max(item.labelheight for item in menuitems) totalh = self.numitems*maxh + (self.numitems + 1)*2*MenuItem.pady x0 = 100 y0 = 400 width = maxw + 2*MenuItem.padx height = maxh + MenuItem.pady for item in menuitems: left = x0 bottom = y0 - maxh - MenuItem.pady item.set_extent(left, bottom, width, height) fig.artists.append(item) y0 -= maxh + MenuItem.pady fig.canvas.mpl_connect('motion_notify_event', self.on_move) def on_move(self, event): draw = False for item in self.menuitems: draw = item.set_hover(event) if draw: self.figure.canvas.draw() break fig = plt.figure() fig.subplots_adjust(left=0.3) props = ItemProperties(labelcolor='black', bgcolor='yellow', fontsize=15, alpha=0.2) hoverprops = ItemProperties(labelcolor='white', bgcolor='blue', fontsize=15, alpha=0.2) menuitems = [] for label in ('open', 'close', 'save', 'save as', 'quit'): def on_select(item): print('you selected %s' % item.labelstr) item = MenuItem(fig, label, props=props, hoverprops=hoverprops, on_select=on_select) menuitems.append(item) menu = Menu(fig, menuitems) plt.show() **Total running time of the script:** ( 0 minutes 0.008 seconds) .. only :: html .. container:: sphx-glr-footer .. container:: sphx-glr-download :download:`Download Python source code: menu.py ` .. container:: sphx-glr-download :download:`Download Jupyter notebook: menu.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_