Matplotlib/Tkinter - customizing toolbar tooltips

匿名 (未验证) 提交于 2019-12-03 02:14:01

问题:

I created an application based on Tkinter that uses Matplotlib for plotting a waveform. I wonder how I could change the tooltips for the Matplotlib toolbar buttons (I need to translate the English descriptions since my application is in Czech language). I'd also like to change/translate or just remove the descriptions (pan/zoom, zoom rect) that appear next to the toolbar panel when clicking on the zoom or pan button.

I found some useful tips concerning how to add or remove buttons from the toolbar, but haven't found any advice for customizing the tooltips/descriptions. I think it would be similar to the former case in that I'd need to create a new toolbar class based on NavigationToolbar2TkAgg and modify it in some way. Any advices on how this could be done? Many thanks in advance.

回答1:

PART 1

So this should be pretty straight forward. The NavigationToolbar2TkAgg class inherits from NavigationToolbar2 which can be found in matplotlib.backend_bases. If you look at NavigationToolbar2TkAgg, you will see that the pop-up text for the buttons is stored in an attribute called self.toolitems. This attribute is inherited from the base class, where it is defined as:

# list of toolitems to add to the toolbar, format is:                                                                              # (                                                                                                                                #   text, # the text of the button (often not visible to users)                                                                    #   tooltip_text, # the tooltip shown on hover (where possible)                                                                    #   image_file, # name of the image for the button (without the extension)                                                         #   name_of_method, # name of the method in NavigationToolbar2 to call                                                             # )                                                                                                                                toolitems = (     ('Home', 'Reset original view', 'home', 'home'),     ('Back', 'Back to  previous view', 'back', 'back'),     ('Forward', 'Forward to next view', 'forward', 'forward'),     (None, None, None, None),     ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),     ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),     (None, None, None, None),     ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),     ('Save', 'Save the figure', 'filesave', 'save_figure'),     ) 

The second item in each tuple is the text that is pops up when you mouse-over the button. To override this, just subclass and make your own version of toolitems.

For example (with filler text):

import numpy as np import Tkinter as tk import matplotlib as mpl from matplotlib.patches import Rectangle from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg  # custom toolbar with lorem ipsum text class CustomToolbar(NavigationToolbar2TkAgg):     def __init__(self,canvas_,parent_):         self.toolitems = (             ('Home', 'Lorem ipsum dolor sit amet', 'home', 'home'),             ('Back', 'consectetuer adipiscing elit', 'back', 'back'),             ('Forward', 'sed diam nonummy nibh euismod', 'forward', 'forward'),             (None, None, None, None),             ('Pan', 'tincidunt ut laoreet', 'move', 'pan'),             ('Zoom', 'dolore magna aliquam', 'zoom_to_rect', 'zoom'),             (None, None, None, None),             ('Subplots', 'putamus parum claram', 'subplots', 'configure_subplots'),             ('Save', 'sollemnes in futurum', 'filesave', 'save_figure'),             )         NavigationToolbar2TkAgg.__init__(self,canvas_,parent_)   class MyApp(object):     def __init__(self,root):         self.root = root         self._init_app()      # here we embed the a figure in the Tk GUI     def _init_app(self):         self.figure = mpl.figure.Figure()         self.ax = self.figure.add_subplot(111)         self.canvas = FigureCanvasTkAgg(self.figure,self.root)         self.toolbar = CustomToolbar(self.canvas,self.root)         self.toolbar.update()         self.plot_widget = self.canvas.get_tk_widget()         self.plot_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=1)         self.toolbar.pack(side=tk.TOP, fill=tk.BOTH, expand=1)         self.canvas.show()      # plot something random     def plot(self):         self.ax.imshow(np.random.normal(0.,1.,size=[100,100]),cmap="hot",aspect="auto")         self.figure.canvas.draw()  def main():     root = tk.Tk()     app = MyApp(root)     app.plot()     root.mainloop()  if __name__ == "__main__":     main() 

This should give you a normal embedded matplotlib figure, but when you mouse-over the buttons you will get something like:

PART 2

The second part of the question is less elegant. The text for "pan/zoom" and "zoom rect" is hardcoded into the pan and zoom methods of the toolbar. The actual text is held in the self.mode attribute of the toolbar. The easiest way to overwrite what this produces is to make subclass wrappers for the baseclass pan and zoom methods.

These wrappers go in the CustomToolbar class from above like:

def pan(self):     NavigationToolbar2TkAgg.pan(self)     self.mode = "I'm panning!" #<--- whatever you want to replace "pan/zoom" goes here     self.set_message(self.mode)  def zoom(self):     NavigationToolbar2TkAgg.zoom(self)     self.mode = "I'm zooming!" #<--- whatever you want to replace "zoom rect" goes here     self.set_message(self.mode) 

This is just one way to do this, another might be to wrap the set_message method to catch and translate specific bits of text.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!