使用wxPython在单独的框架中将导航工具栏嵌入FigureCanvas

2024-10-01 00:30:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我想将matplotlib.backends.backends_wx.NavigationToolbar2Wx添加到我正在开发的GUI中,但是我不希望它出现在FigureCanvas上,因为这会迫使我的布局变得相当笨拙。有没有一种方法可以将NavigationToolbar2Wx添加到GUI的另一部分而不是它所附加到的画布上?我特别想要以下的布局

+------------------------------------------------------------------------+
| +--------------------------------------------------------------------+ |
| |                                                                    | |
| |                                                                    | |
| |                                                                    | |
| |                                                                    | |
| |                            FigureCanvas                            | |
| |                                                                    | |
| |                                                                    | |
| +--------------------------------------------------------------------+ |
| +--------------------------------------------------------------------+ |
| |  TextCtrl   TextCtrl        NavToolbar           TextCtrl  Button  | |
| +--------------------------------------------------------------------+ |
|                                                                        |
|                               More GUI here                            |
|                                                                        |
+------------------------------------------------------------------------+

其中FigureCanvas和它下面的部分在同一个垂直BoxSizer,带有{}的区域是一个水平BoxSizer。在

我尝试了各种各样的方法,比如显而易见的构造工具栏,将sizer设置为水平BoxSizer,并将其添加到BoxSizer,但是它没有绘制(尽管{}将突出显示它应该在工具栏上的, and when I close the window it throws a segfault. If I don't set the sizer for the toolbar, the behavior is identical except it doesn't throw a segfault. I am making sure to call.Realize()and.Update()`的位置,但是到目前为止我还没有运气。在

我想做的是可能的,还是必须手动实现按钮和行为?在


Tags: andthe方法水平itgui布局backends
1条回答
网友
1楼 · 发布于 2024-10-01 00:30:05

扩展一下我的评论,这是一个几乎可以:-)工作的示例,忽略了一些琐碎的部分。我使用wx.lib.agw.buttonpanel作为我的工具栏,但是粗糙的任何其他工具也可以。在

import wx.lib.agw.buttonpanel as BP
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx


#               plot panel               -
class PanelWithCanvas(wx.Panel):
    """
    This panel contains plot figure and other things...
    """
    def __init__(self, parent, frame):
        wx.Panel.__init__(self, parent)

        self.frame = frame

        ...

        # create figure
        self.figure = plt.Figure()
        self.axes  = self.figure.add_subplot(111)
        self.axes.grid()
        # attach a canvas to the figure
        self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure) 

        # create the default matplotlib toolbar and attach it to the canvas
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        # realize and hide it, since it will be replaced by a better one
        self.toolbar.Realize()
        self.toolbar.Hide()

        # create a new plot toolbar to replace the default one
        self.ptb = plotToolbar(self)

        ...


#               plot toolbar               -
class plotToolbar(BP.ButtonPanel):
    """
    Create small toolbar which is added to the main panel
    par:  parent
    """
    def __init__(self, par):
        BP.ButtonPanel.__init__(self, par)

        # PanelWithCanvas
        self.pwc = par

        self.ID_FIT = wx.NewId()
        self.ID_ZOOM = wx.NewId()
        self.ID_PAN = wx.NewId()
        self.ID_SAVE = wx.NewId()

        self.AddSpacer()

        btn1 = BP.ButtonInfo(self, self.ID_FIT, bitmaps['zoomfit'].GetBitmap(),
                         shortHelp='Fit plot extents')
        self.AddButton(btn1)
        self.Bind(wx.EVT_BUTTON, self.ZoomFit, btn1)

        self.btnzoom = BP.ButtonInfo(self, self.ID_ZOOM, bitmaps['zoom'].GetBitmap(),
                         kind=wx.ITEM_CHECK, shortHelp='Zoom in/out')
        self.AddButton(self.btnzoom)
        self.Bind(wx.EVT_BUTTON, self.Zoom, self.btnzoom)

        self.btnpan = BP.ButtonInfo(self, self.ID_PAN, bitmaps['pan'].GetBitmap(),
                         kind=wx.ITEM_CHECK, shortHelp='Move plot')
        self.AddButton(self.btnpan)
        self.Bind(wx.EVT_BUTTON, self.Pan, self.btnpan)

        btnsav = BP.ButtonInfo(self, self.ID_SAVE, bitmaps['saveimage'].GetBitmap(),
                         shortHelp='Save image')
        self.AddButton(btnsav)
        self.Bind(wx.EVT_BUTTON, self.SaveImage, btnsav)

        self.AddSpacer()

        self.DoLayout()

    def ZoomFit(self, event):
        self.pwc.toolbar.home()
        event.Skip()

    def Zoom(self, event):
        self.pwc.toolbar.zoom()
        event.Skip()

    def Pan(self, event):
        self.pwc.toolbar.pan()
        event.Skip()

    def SaveImage(self, event):
        self.pwc.toolbar.save_figure(None)
        event.Skip()

请注意,您必须自己管理按钮的行为,因为其中一些按钮是只按按钮(fit all,save),有些是切换(缩放,平移),并且是互斥的。。。或者您可以像NavigationToolbar2Wx中那样将它们全部保留为按钮。希望这有帮助。在

相关问题 更多 >