python matplotlib工具栏源码探析二之添加、删除内置工具项的案例


Posted in Python onFebruary 25, 2021

从matplotlib工具栏源码探析一(禁用工具栏、默认工具栏和工具栏管理器三种模式的差异)一文可知matplotlib内置实现了多个工具项的实现,而默认工具栏中的工具项只是其中的一部分,有没有方法直接管理工具栏,添加、删除内置工具项?

matplotlib内置的工具项

由源码可知,matplotlib.backend_tools.default_tools变量为字典类型,实例化了基于matplotlib.backend_tools.ToolBase类定义的内置工具项。

源码

default_tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward,
     'zoom': ToolZoom, 'pan': ToolPan,
     'subplots': 'ToolConfigureSubplots',
     'save': 'ToolSaveFigure',
     'grid': ToolGrid,
     'grid_minor': ToolMinorGrid,
     'fullscreen': ToolFullScreen,
     'quit': ToolQuit,
     'quit_all': ToolQuitAll,
     'allnav': _ToolEnableAllNavigation,
     'nav': _ToolEnableNavigation,
     'xscale': ToolXScale,
     'yscale': ToolYScale,
     'position': ToolCursorPosition,
     _views_positions: ToolViewsPositions,
     'cursor': 'ToolSetCursor',
     'rubberband': 'ToolRubberband',
     'help': 'ToolHelp',
     'copy': 'ToolCopyToClipboard',
     }

验证

import matplotlib.pyplot as plt
import matplotlib as mpl
from pprint import pprint

plt.rcParams['toolbar'] = 'toolmanager'
fig = plt.gcf()
pprint(mpl.backend_tools.default_tools)

输出

{'allnav': <class 'matplotlib.backend_tools._ToolEnableAllNavigation'>,
 'back': <class 'matplotlib.backend_tools.ToolBack'>,
 'copy': 'ToolCopyToClipboard',
 'cursor': 'ToolSetCursor',
 'forward': <class 'matplotlib.backend_tools.ToolForward'>,
 'fullscreen': <class 'matplotlib.backend_tools.ToolFullScreen'>,
 'grid': <class 'matplotlib.backend_tools.ToolGrid'>,
 'grid_minor': <class 'matplotlib.backend_tools.ToolMinorGrid'>,
 'help': 'ToolHelp',
 'home': <class 'matplotlib.backend_tools.ToolHome'>,
 'nav': <class 'matplotlib.backend_tools._ToolEnableNavigation'>,
 'pan': <class 'matplotlib.backend_tools.ToolPan'>,
 'position': <class 'matplotlib.backend_tools.ToolCursorPosition'>,
 'quit': <class 'matplotlib.backend_tools.ToolQuit'>,
 'quit_all': <class 'matplotlib.backend_tools.ToolQuitAll'>,
 'rubberband': 'ToolRubberband',
 'save': 'ToolSaveFigure',
 'subplots': 'ToolConfigureSubplots',
 'viewpos': <class 'matplotlib.backend_tools.ToolViewsPositions'>,
 'xscale': <class 'matplotlib.backend_tools.ToolXScale'>,
 'yscale': <class 'matplotlib.backend_tools.ToolYScale'>,
 'zoom': <class 'matplotlib.backend_tools.ToolZoom'>}

使用工具栏管理器管理内置工具项

由源码可知默认工具栏模式toolbar2模式没有提供添加、删除工具项的接口。因此,管理工具栏需要使用工具栏管理器模式toolmanager,与该模式相关的重要定义有:

  • matplotlib.backend_bases.ToolContainerBase(toolmanager)类:工具栏容器的基类,定义了工具栏编辑的方法。构造函数参数为toolmanager,表示工具栏容器容纳的工具栏。
  • matplotlib.backend_managers.ToolManager(figure=None)类:管理用户触发工具栏工具项按钮而产生的动作。matplotlib.backend_tools.ToolBase类:所有工具栏工具项的基类,所有工具项均由matplotlib.backend_managers.ToolManager实例化。
  • matplotlib.backend_tools.default_tools变量:字典类型,实例化基于matplotlib.backend_tools.ToolBase类定义的内置工具项。
  • matplotlib.backend_tools.default_toolbar_tools变量:嵌套列表,以类似格式[[分组1, [工具1, 工具2 ...]], [分组2, [...]]]定义工具栏布局。
  • matplotlib.backend_tools.add_tools_to_container函数:设置toolbarmanager模式默认工具栏。

使用系统函数实现添加工具项

根据源码可知,matplotlib.backend_tools.add_tools_to_container函数可以设置toolbarmanager模式默认工具栏。

案例

案例说明:为工具栏添加全屏切换工具项。

import matplotlib.pyplot as plt
import matplotlib as mpl

plt.rcParams['toolbar'] = 'toolmanager'
fig = plt.gcf()
# 通过mpl.backend_tools.add_tools_to_container函数添加工具项
mpl.backend_tools.add_tools_to_container(fig.canvas.manager.toolbar, tools=[['foo', [ 'fullscreen']]])
plt.show()

案例解析:add_tools_to_container函数有两个参数containertools,由源码可知container参数的值应为fig.canvas.manager.toolbartools参数按照[[分组1, [工具1, 工具2 ...]], [分组2, [...]]]格式取值。

python matplotlib工具栏源码探析二之添加、删除内置工具项的案例

使用工具栏管理器实现添加、删除内置工具项

根据源码可知:

添加内置工具项有两种方法

  • toolbar对象可以通过add_tool方法添加内置工具项,参数为nametoolname为工具项的名称,tool为添加的工具项对应的类或者字符串。
  • toolbar对象可以通过add_toolitem方法添加内置工具项,参数为namegrouppositionimage_filedescriptiontogglename为工具项的名称,group为工具项所在组,position为工具项在组中的位置,取值为列表索引,一般取-1即在所在组末尾追加,设置为0即在所在组的首位,image_file为工具项图像,值为字符串,description为工具项描述, toggle为是否为切换式工具项,布尔值。
  • 删除内置工具项有两种方法
  • toolbar对象可以通过remove_toolitem方法删除内置工具项,参数为name,即工具项的名称。
  • toolmanager对象可以通过remove_tool方法删除内置工具项,参数为name,即工具项的名称。

案例

案例说明:删除向前工具项,添加全屏切换工具项。

import matplotlib.pyplot as plt
import matplotlib as mpl

plt.rcParams['toolbar'] = 'toolmanager'
fig = plt.gcf()

fig.canvas.manager.toolmanager.remove_tool('forward')
fig.canvas.manager.toolbar.remove_toolitem('back')
fig.canvas.manager.toolbar.add_tool('quit', 'foo')
fig.canvas.manager.toolbar.add_toolitem('fullscreen', 'foo', -1,'fullscreen','fullscreen',False) 

plt.show()

python matplotlib工具栏源码探析二之添加、删除内置工具项的案例

总结

通过工具栏管理器添加、删除内置工具项的方法很多种,需要注意调用对象、方法、参数,阅读下面的matplotlib源码可能会有所启发。

相关源码

matplotlib.backends.backend_qt5模块

class FigureManagerQT(FigureManagerBase):
 self.toolbar = self._get_toolbar(self.canvas, self.window)

 if self.toolmanager:
  backend_tools.add_tools_to_manager(self.toolmanager)
  if self.toolbar:
   backend_tools.add_tools_to_container(self.toolbar)

 if self.toolbar:
  self.window.addToolBar(self.toolbar)
  tbs_height = self.toolbar.sizeHint().height()
 else:
  tbs_height = 0
def _get_toolbar(self, canvas, parent):
  # must be inited after the window, drawingArea and figure
  # attrs are set
  if matplotlib.rcParams['toolbar'] == 'toolbar2':
   toolbar = NavigationToolbar2QT(canvas, parent, True)
  elif matplotlib.rcParams['toolbar'] == 'toolmanager':
   toolbar = ToolbarQt(self.toolmanager, self.window)
  else:
   toolbar = None
  return toolbar
class ToolbarQt(ToolContainerBase, QtWidgets.QToolBar):
 def __init__(self, toolmanager, parent):
  ToolContainerBase.__init__(self, toolmanager)
  QtWidgets.QToolBar.__init__(self, parent)
  self.setAllowedAreas(
   QtCore.Qt.TopToolBarArea | QtCore.Qt.BottomToolBarArea)
  message_label = QtWidgets.QLabel("")
  message_label.setAlignment(
   QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
  message_label.setSizePolicy(
   QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
         QtWidgets.QSizePolicy.Ignored))
  self._message_action = self.addWidget(message_label)
  self._toolitems = {}
  self._groups = {}

 def add_toolitem(
   self, name, group, position, image_file, description, toggle):

  button = QtWidgets.QToolButton(self)
  if image_file:
   button.setIcon(NavigationToolbar2QT._icon(self, image_file))
  button.setText(name)
  if description:
   button.setToolTip(description)

  def handler():
   self.trigger_tool(name)
  if toggle:
   button.setCheckable(True)
   button.toggled.connect(handler)
  else:
   button.clicked.connect(handler)

  self._toolitems.setdefault(name, [])
  self._add_to_group(group, name, button, position)
  self._toolitems[name].append((button, handler))

 def _add_to_group(self, group, name, button, position):
  gr = self._groups.get(group, [])
  if not gr:
   sep = self.insertSeparator(self._message_action)
   gr.append(sep)
  before = gr[position]
  widget = self.insertWidget(before, button)
  gr.insert(position, widget)
  self._groups[group] = gr

 def toggle_toolitem(self, name, toggled):
  if name not in self._toolitems:
   return
  for button, handler in self._toolitems[name]:
   button.toggled.disconnect(handler)
   button.setChecked(toggled)
   button.toggled.connect(handler)

 def remove_toolitem(self, name):
  for button, handler in self._toolitems[name]:
   button.setParent(None)
  del self._toolitems[name]

 def set_message(self, s):
  self.widgetForAction(self._message_action).setText(s

matplotlib.backend_tools模块

def add_tools_to_container(container, tools=default_toolbar_tools):
 """
 Add multiple tools to the container.

 Parameters
 ----------
 container : Container
  `backend_bases.ToolContainerBase` object that will get the tools added.
 tools : list, optional
  List in the form ``[[group1, [tool1, tool2 ...]], [group2, [...]]]``
  where the tools ``[tool1, tool2, ...]`` will display in group1.
  See `add_tool` for details.
 """

 for group, grouptools in tools:
  for position, tool in enumerate(grouptools):
   container.add_tool(tool, group, position)
def add_tools_to_manager(toolmanager, tools=default_tools):
 """
 Add multiple tools to a `.ToolManager`.

 Parameters
 ----------
 toolmanager : `.backend_managers.ToolManager`
  Manager to which the tools are added.
 tools : {str: class_like}, optional
  The tools to add in a {name: tool} dict, see `add_tool` for more
  info.
 """

 for name, tool in tools.items():
  toolmanager.add_tool(name, tool)

到此这篇关于python matplotlib工具栏源码探析二之添加、删除内置工具项的案例的文章就介绍到这了,更多相关python matplotlib内置工具项内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中为feedparser设置超时时间避免堵塞
Sep 28 Python
Python实现网络端口转发和重定向的方法
Sep 19 Python
python中Pycharm 输出中文或打印中文乱码现象的解决办法
Jun 16 Python
快速了解Python开发中的cookie及简单代码示例
Jan 17 Python
python输入多行字符串的方法总结
Jul 02 Python
python flask web服务实现更换默认端口和IP的方法
Jul 26 Python
Python中常见的数制转换有哪些
May 27 Python
浅谈Keras参数 input_shape、input_dim和input_length用法
Jun 29 Python
python 基于DDT实现数据驱动测试
Feb 18 Python
python实现图片转字符画
Feb 19 Python
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
Apr 14 Python
python flappy bird小游戏分步实现流程
Feb 15 Python
python matplotlib工具栏源码探析三之添加、删除自定义工具项的案例详解
Feb 25 #Python
python实现简单文件读写函数
Feb 25 #Python
python pygame 愤怒的小鸟游戏示例代码
Feb 25 #Python
python网络爬虫实现发送短信验证码的方法
Feb 25 #Python
python openpyxl模块的使用详解
Feb 25 #Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
Feb 25 #Python
python如何实现递归转非递归
Feb 25 #Python
You might like
phpmyadmin出现Cannot start session without errors问题解决方法
2014/08/14 PHP
php获取随机数组列表的方法
2014/11/13 PHP
Javascript 复制数组实现代码
2009/11/26 Javascript
Firebug入门指南(Firefox浏览器)
2010/08/21 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
js点击列表文字对应该行显示背景颜色的实现代码
2015/08/05 Javascript
JQuery日历插件My97DatePicker日期范围限制
2016/01/20 Javascript
Vue.JS入门教程之处理表单
2016/12/01 Javascript
javascript自执行函数
2017/02/10 Javascript
Node.js+ES6+dropload.js实现移动端下拉加载实例
2017/06/01 Javascript
AngularJS实现的JSONP跨域访问数据传输功能详解
2017/07/20 Javascript
React-router v4 路由配置方法小结
2017/08/08 Javascript
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
form表单数据封装成json格式并提交给服务器的实现方法
2017/12/14 Javascript
微信小程序按钮去除边框线分享页面功能
2018/08/27 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
javascript面向对象创建对象的方式小结
2019/07/29 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
解决layui下拉框监听问题(监听不到值的变化)
2019/09/28 Javascript
js实现带积分弹球小游戏
2020/07/21 Javascript
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
2017/09/08 Python
我们为什么要减少Python中循环的使用
2019/07/10 Python
英国日常交易网站:Wowcher
2018/09/04 全球购物
北美主要的汽车零部件零售商:AutoShack.com
2019/02/23 全球购物
澳大利亚第一旅行车和房车配件店:Caravan RV Camping
2020/12/26 全球购物
考博自荐信
2013/10/25 职场文书
群众路线批评与自我批评
2014/02/06 职场文书
租赁意向书范本
2014/04/01 职场文书
经典团队口号大全
2014/06/21 职场文书
2014年招生工作总结
2014/11/26 职场文书
2016年第十四个公民道德宣传日活动总
2016/04/01 职场文书
Python加密与解密模块hashlib与hmac
2022/06/05 Python