如图所示将 NavigationToolbar 放在不同的 Window/ Panel 中

Putting NavigationToolbar in different Window/ Panel as Figure

首先,我在 Windows 10 上使用 wxPython-4.0.4、Python 3.7.2 和 matplotlib 3.0.3。这是我的问题。

我想要一个(大)图形和 NavigationToolbar 嵌入到 wxPython。该图应该是可滚动的,而工具栏应该保持在原处。我的方法是将图形放入可滚动面板 (wx.lib.scrolledpanel.ScrolledPanel) 并将工具栏放在主面板的顶部。这是我的代码:

import wx

locale = wx.Locale.GetSystemLanguage()  # fix to 'wx._core.wxAssertionError'

from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
from wx.lib.scrolledpanel import ScrolledPanel


class Main_Panel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        ### Create Widgets
        self.plot_panel = ScrolledPanel(self)

        self.figure = Figure((10,10))               # creating figure and toolbar
        self.canvas = FigureCanvas(self.plot_panel, -1, self.figure)
        self.toolbar = NavigationToolbar(self.canvas)

        self.subplot = self.figure.add_subplot(111) # just some arbitrary plot
        self.subplot.plot([1,2,3], [2,4,1])

        ### Implement Widgets
        self.plot_sizer = wx.BoxSizer(wx.VERTICAL)  # sizer for scrollable plot panel
        self.plot_sizer.Add(self.toolbar)           # putting toolbar here does work but it is also scrolling
        self.plot_sizer.Add(self.canvas)
        self.plot_panel.SetSizer(self.plot_sizer)
        self.plot_panel.SetupScrolling()

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)  # sizer for main panel
##        self.main_sizer.Add(self.toolbar)         # putting toolbar here does not work
        self.main_sizer.Add(self.plot_panel, proportion=1, flag=wx.EXPAND)
        self.SetSizer(self.main_sizer)


def main():
    app = wx.App()
    app.locale = wx.Locale(locale)  # fix to 'wx._core.wxAssertionError'

    frame = wx.Frame(None)
    Main_Panel(frame)
    frame.Show(True)
    app.MainLoop()

if __name__ == '__main__':
    main()

问题是我无法将图形和工具栏放置到两个不同的面板中。如果我将它们放在同一个位置上,则如果我滚动(很明显),工具栏不会保留在屏幕上。但是,如果我尝试通过 "main_sizer" 将其添加到 "top" 面板,它要么根本不显示,要么在 "ScrolledPanel" 内也可滚动,但不起作用。

我也尝试将带有 "ScrolledPanel" 的整个部分放到一个单独的 class 中,但我也无法使工具栏工作。

有人对此有解决方案吗?甚至有可能吗?我是否必须创建自己的工具栏?

此外,为什么我需要将这两行代码放入带有注释 "fix to wx._core.wxAssertionError'" 的代码中,以使程序 运行 没有上述错误?

感谢您提供的任何帮助!

由于还没有人回复我的 post,我想 post 我刚刚找到的可能方法 here

在此示例中,工具栏已创建但未在 UI 中实现,并通过 self.toolbar.Hide() 隐藏。 然后通过 wx 按钮和工具栏属性访问工具栏的功能:self.toolbar.zoom()。这样,按钮可以放置在 window 中的其他位置,甚至可能放置在另一个 window 中,尽管我还没有测试后者。

如果没有人提出更好的解决方案,我希望这至少能对其他人有所帮助。

至于wx._core.wxAssertionError,我还不知道怎么解决。特别是,由于几乎每次我想尝试一些以某种方式创建工具栏的示例代码时都会出现此错误。有时我在 post 中的解决方法有所帮助,但有时却没有。