Matplotlib/Tkinter - 自定义工具栏提示信息

3
我创建了一个基于Tkinter的应用程序,使用Matplotlib绘制波形。我想知道如何更改Matplotlib工具栏按钮的工具提示(需要翻译英文描述,因为我的应用程序是捷克语)。我还想更改/翻译或仅删除在单击缩放或平移按钮时出现在工具栏面板旁边的缩放或平移的描述(pan / zoomzoom rect)。
我发现了一些有关如何添加或删除工具栏中按钮的有用提示,但没有找到任何有关自定义工具提示/描述的建议。我认为这与前一种情况类似,我需要基于NavigationToolbar2TkAgg创建一个新的工具栏类,并以某种方式进行修改。有关如何完成此操作的任何建议?非常感谢。
1个回答

12

第一部分

这应该相当简单。 NavigationToolbar2TkAgg 类继承自 NavigationToolbar2,它可以在 matplotlib.backend_bases 中找到。如果您查看 NavigationToolbar2TkAgg,您会发现按钮的弹出文本存储在名为 self.toolitems 的属性中。这个属性是从基类继承而来的,在那里定义为:

# 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'),
    )
每个元组中的第二项是鼠标悬停在按钮上时弹出的文本。要覆盖这个默认文本,只需创建子类并制作自己版本的toolitems即可。
例如(使用填充文本):
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()

这应该给您一个正常的嵌入式matplotlib图形,但当您将鼠标悬停在按钮上时,会得到类似于以下内容的东西:

自定义工具栏文本示例

第二部分

问题的第二部分不太优雅。 “pan / zoom”和“zoom rect”的文本是硬编码到工具栏的panzoom方法中的。 实际文本保存在工具栏的self.mode属性中。 覆盖此属性的最简单方法是为基类panzoom方法创建子类包装器。

这些包装器放置在上面的CustomToolbar类中,如下所示:

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)

这只是一种实现方式,另一种可能是包装set_message方法以捕获和翻译特定的文本片段。


非常感谢,它的工作方式正是我想要的 :-). - JirkaK
toolbar.update() 究竟是做什么的?我使用了这个例子来修改导航工具栏的默认行为,效果很好,但是 update() 似乎没有起到作用。 - Kevin S.
它更新了 NavigationToolbar2TkAgg 对象的内部状态,我认为它也等待已排队的请求被完成。 - ebarr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接