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实现拼接多张图片的方法
Dec 01 Python
通过代码实例展示Python中列表生成式的用法
Mar 31 Python
python 中if else 语句的作用及示例代码
Mar 05 Python
详谈Python中列表list,元祖tuple和numpy中的array区别
Apr 18 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
Jan 05 Python
python使用pipeline批量读写redis的方法
Feb 18 Python
Python dict和defaultdict使用实例解析
Mar 12 Python
Python中格式化字符串的四种实现
May 26 Python
Python小白不正确的使用类变量实例
May 29 Python
解决Windows下python和pip命令无法使用的问题
Aug 31 Python
python将下载到本地m3u8视频合成MP4的代码详解
Nov 24 Python
Python WSGI 规范简介
Apr 11 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
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
php生成网页桌面快捷方式
2017/05/05 PHP
jquery ajax return没有返回值的解决方法
2011/10/20 Javascript
使用jquery读取html5 localstorage的值的方法
2013/01/04 Javascript
jsp js鼠标移动到指定区域显示选项卡离开时隐藏示例
2013/06/14 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
数组Array的排序sort方法
2017/02/17 Javascript
node koa2实现上传图片并且同步上传到七牛云存储
2017/07/31 Javascript
JavaScript屏蔽Backspace键的实现代码
2017/11/02 Javascript
Node.js上传文件功能之服务端如何获取文件上传进度
2018/02/05 Javascript
angular json对象push到数组中的方法
2018/02/27 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
jQuery实现的隔行变色功能【案例】
2019/02/18 jQuery
Layui table field初始化加载时进行隐藏的方法
2019/09/19 Javascript
浅谈vue获得后台数据无法显示到table上面的坑
2020/08/13 Javascript
在Python中使用pngquant压缩png图片的教程
2015/04/09 Python
Python操作csv文件实例详解
2017/07/31 Python
Python设计模式之MVC模式简单示例
2018/01/10 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
python如何拆分含有多种分隔符的字符串
2018/03/20 Python
Python使用matplotlib绘制三维图形示例
2018/08/25 Python
解决webdriver.Chrome()报错:Message:'chromedriver' executable needs to be in Path
2019/06/12 Python
详解Python 多线程 Timer定时器/延迟执行、Event事件
2019/06/27 Python
python中的RSA加密与解密实例解析
2019/11/18 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
美国在线工具商店:Acme Tools
2018/06/26 全球购物
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
美国在线家具网站:GDFStudio
2021/03/13 全球购物
linux面试题参考答案(6)
2014/08/29 面试题
10的分与合教学反思
2014/04/30 职场文书
养牛场项目建议书
2014/05/13 职场文书
开工仪式策划方案
2014/05/23 职场文书
春游踏青活动方案
2014/08/14 职场文书
评先进个人材料
2014/12/29 职场文书
电力工程合作意向书
2015/05/11 职场文书
2016大学生暑期社会实践心得体会
2016/01/14 职场文书