Размещение NavigationToolbar в другом окне / панели как на рисунке - PullRequest
1 голос
/ 18 марта 2019

Предварительно, я использую wxPython-4.0.4, Python 3.7.2 и matplotlib 3.0.3 в Windows 10. Вот моя проблема.

Я хотел бы иметь (большую) фигуру и панель навигации 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», он либо вообще не будет отображаться, либо будет прокручиваться внутри «ScrolledPanel», но не работает.

Я также попытался поместить всю деталь с помощью ScrolledPanel в отдельный класс, но не смог заставить работать панель инструментов.

У кого-нибудь есть решение для этого? Это вообще возможно? Нужно ли мне создавать собственную панель инструментов?

Кроме того, зачем мне нужно поместить две строки в код с комментарием "fix to wx._core.wxAssertionError '", чтобы программа могла работать без указанной ошибки?

Спасибо за любую помощь, которую вы можете оказать!

1 Ответ

0 голосов
/ 20 марта 2019

Поскольку на мой пост еще никто не ответил, я хочу опубликовать возможный подход, который я только что нашел здесь .

В этом примере панель инструментов создана, но не реализована в пользовательском интерфейсе и скрыта через self.toolbar.Hide(). Функциональные возможности панели инструментов затем доступны через кнопки wx и атрибуты панелей инструментов: self.toolbar.zoom(). Таким образом, кнопки можно разместить где-то еще в окне и, возможно, даже в другом окне, хотя последнее я не проверял.

Надеюсь, это хотя бы немного поможет другим, если никто не придет с лучшим решением.

Что касается wx._core.wxAssertionError, я до сих пор не знаю, как его решить. Тем более, что эта ошибка появлялась почти каждый раз, когда я хотел опробовать некоторый пример кода, который так или иначе создает панель инструментов. Иногда мой обходной путь в посте помогал, а иногда - нет.

...