按钮概述
按钮是图形化界面(GUI)中常见的控件,matplotlib
也提供按钮功能。matplotlib
中的按钮属于部件(widgets),matplotlib
中的部件都是中性(neutral )
的,即与具体后端实现无关。
按钮具体实现定义为matplotlib.widgets.Button
类,继承关系为:Widget->AxesWidget->Button
。
Button
类的类签名为class matplotlib.widgets.Button(ax, label, image=None, color='0.85', hovercolor='0.95')
Button
类构造函数的参数为:
ax
:放置按钮的容器,类型为matplotlib.axes.Axes
的实例。label
:按钮文本,类型为字符串。image
:按钮上的图片,默认为None
即没有图片,类型要求为PIL图像
或图像二维数组。coloer
:按钮颜色。hovercloer
:鼠标经过按钮时按钮的颜色。
Button
类的属性为:
ax
:放置按钮的容器,类型为matplotlib.axes.Axes
的实例。label
:按钮文本。coloer
:按钮颜色。hovercloer
:鼠标经过按钮时按钮的颜色。
Button
类最常用的方法为 on_clicked(func)
:它的参数为回调函数,用于绑定按钮的点击事件。
按钮案例
实现功能
在绘制的图表右下方添加两个按钮,左侧按钮添加了图片,点击后可全屏窗口,右侧按钮为普通按钮,点击后将窗口恢复为默认大小。
代码解析
代码中关键点直接添加在注释中。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
# 按钮文本使用中文,因此配置中文字体支持
plt.rcParams['font.family'] = 'SimHei'
# 绘制图表
plt.plot([1,2])
# 因为默认子图周边预留空间太小,容易和按钮重叠,所以调整图表所在子图大小,在下方为按钮预留空间
plt.subplots_adjust(bottom=0.2)
# 获取当前图像对象
fig=plt.gcf()
# 创建左侧按钮图片对象
from PIL import Image
PATH_TO_ICON = r"c:\max.jpg"
i = Image.open(PATH_TO_ICON)
# 创建按钮事件回调函数
class Button_handlers():
# 窗口全屏
def fullscreen(self, event):
fig.canvas.manager.window.showFullScreen()
# 恢复窗口大小
def normal(self, event):
fig.canvas.manager.window.showNormal()
# 创建容纳按钮的容器axes, plt.axes([0.7, 0.05, 0.1, 0.075])中的
# 列表代表容器子图所在方位,[左, 下, 宽, 高],单位为图像长或宽的比例。
# plt.axes([0.7, 0.05, 0.1, 0.075])即子图的左边缘位于图像宽度70%位置,
# 下边缘距离图像下边缘宽度5%,子图宽度为图像宽度的10%,子图高度为图像高度的7.5%
ax_fullscreen = plt.axes([0.7, 0.05, 0.1, 0.075])
ax_normal = plt.axes([0.81, 0.05, 0.1, 0.075])
# 实例化全屏按钮,标签设置为空,防止与图片重叠
btn_fullscreen= Button(ax_fullscreen, ' ',image=i)
# 利用on_clicked方法绑定事件
btn_fullscreen.on_clicked(Button_handlers().fullscreen)
# 实例化恢复大小按钮
btn_normal = Button(ax_normal, '恢复正常')
btn_normal.on_clicked(Button_handlers().normal)
plt.show()
按钮点击事件回调函数原理解析
以下为Buttons
类部分源码,根据源码可知,按钮点击事件在内部绑定的是_release
方法,release
方法最终调用func(event)
,func
为on_clicked
方法绑定的回调函数。所以回调函数func
必须调用1个参数即event
,如果在定义回调函数时不定义参数就会报错。
self.connect_event('button_press_event', self._click)
self.connect_event('button_release_event', self._release)
self.connect_event('motion_notify_event', self._motion)
def _release(self, event):
if (self.ignore(event)
or event.canvas.mouse_grabber != self.ax):
return
event.canvas.release_mouse(self.ax)
if (not self.eventson
or event.inaxes != self.ax):
return
for cid, func in self.observers.items():
func(event)
def on_clicked(self, func):
"""
Connect the callback function *func* to button click events.
Returns a connection id, which can be used to disconnect the callback.
"""
cid = self.cnt
self.observers[cid] = func
self.cnt += 1
return cid
总结
总体上matplotlib
按钮使用还是比较简单的,属性和方法都比较少。稍有麻烦可能就是按钮的容器,即构造函数中的ax
属性,注意不要和主要绘图图表的子图混淆了,按钮默认会填满整个子图区域,按钮创建需要一个单独的子图。