mirror of
https://github.com/Estom/notes.git
synced 2026-02-06 03:54:22 +08:00
194 lines
5.1 KiB
Markdown
194 lines
5.1 KiB
Markdown
# 菜单
|
|
|
|

|
|
|
|
输出:
|
|
|
|
```python
|
|
100 371 91 29
|
|
100 342 91 29
|
|
100 313 91 29
|
|
100 284 91 29
|
|
100 255 91 29
|
|
```
|
|
|
|
```python
|
|
import numpy as np
|
|
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.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()
|
|
```
|
|
|
|
## 下载这个示例
|
|
|
|
- [下载python源码: menu.py](https://matplotlib.org/_downloads/menu.py)
|
|
- [下载Jupyter notebook: menu.ipynb](https://matplotlib.org/_downloads/menu.ipynb) |