按钮概述

按钮是图形化界面(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)funcon_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属性,注意不要和主要绘图图表的子图混淆了,按钮默认会填满整个子图区域,按钮创建需要一个单独的子图。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐