【问题标题】:Matplotlib/Tkinter - customizing toolbar tooltipsMatplotlib/Tkinter - 自定义工具栏工具提示
【发布时间】:2014-04-19 17:01:45
【问题描述】:

我创建了一个基于 Tkinter 的应用程序,它使用 Matplotlib 来绘制波形。我想知道如何更改 Matplotlib 工具栏按钮的工具提示(我需要翻译英文描述,因为我的应用程序是捷克语)。我还想更改/翻译或删除单击缩放或平移按钮时工具栏面板旁边显示的说明(pan/zoomzoom rect)。

我发现了一些关于如何从工具栏中添加或删除按钮的有用提示,但没有找到任何自定义工具提示/描述的建议。我认为这与前一种情况类似,因为我需要基于NavigationToolbar2TkAgg 创建一个新的工具栏类并以某种方式对其进行修改。关于如何做到这一点的任何建议?非常感谢。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    第 1 部分

    所以这应该很简单。 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 图,但是当你将鼠标悬停在按钮上时,你会得到类似的东西:

    第 2 部分

    问题的第二部分不太优雅。 “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 方法来捕获和翻译特定的文本位。

    【讨论】:

    • 非常感谢,它的工作方式正是我想要的 :-)。
    • toolbar.update() 到底是做什么的?我用这个例子来修改导航工具栏的默认行为,除了update() 似乎没有什么不同之外,它工作得很好。
    • 它更新 NavigationToolbar2TkAgg 对象的内部状态,我认为它也会等待队列请求完成。
    猜你喜欢
    • 2013-06-23
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    相关资源
    最近更新 更多