wxPython: хороший способ наложить wx.Panel на существующую wx.Panel.

У меня есть wx.Frame, в котором есть главная wx.Panel с несколькими виджетами внутри. Я хочу, чтобы одна кнопка вызывала «панель помощи». Эта панель справки, вероятно, будет wx.Panel, и я хочу, чтобы она перекрывала всю основную панель wx.Panel (не включая строку меню wx.Frame). На кнопке справки должна быть какая-то кнопка закрытия, которая заставит ее снова исчезнуть.

Каков хороший способ добиться этого? Я просмотрел wx.Notebook, но не нашел способа сделать так, чтобы вкладки не отображались.

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


person Ram Rachum    schedule 23.06.2009    source источник


Ответы (2)


Есть несколько способов

а) вы можете создать пользовательскую дочернюю панель и сделать ее такого же размера и положения на уровне 0,0 среди всех дочерних виджетов. нет необходимости уничтожать его, просто показать / скрыть, он также изменяет размер с родительским фреймом

б) всплывающее окно wx.PopupWindow или производный класс и размещение и размер в правильном месте

так, как предлагается в a) вот пример, где все элементы управления помещаются в панель с помощью сайзера, так как создается отдельный cntrl справки, который можно показать/скрыть от кнопки, но вы можете создать собственный cntrl, который скрывает себя при нажатии кнопки закрытия

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)

        self.panel = wx.Panel(self)

        # create controls
        self.cntrlPanel = wx.Panel(self.panel)
        stc1 = wx.StaticText(self.cntrlPanel, label="wow it works")
        stc2 = wx.StaticText(self.cntrlPanel, label="yes it works")
        btn = wx.Button(self.cntrlPanel, label="help?")
        btn.Bind(wx.EVT_BUTTON, self._onShowHelp)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(stc1)
        sizer.Add(stc2)
        sizer.Add(btn)
        self.cntrlPanel.SetSizer(sizer)


        # create help panel
        self.helpPanel = wx.Panel(self.panel)
        self.stcHelp = wx.StaticText(self.helpPanel, label="help help help\n"*8)
        btn = wx.Button(self.helpPanel, label="close[x]")
        btn.Bind(wx.EVT_BUTTON, self._onShowCntrls)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.stcHelp)
        sizer.Add(btn)
        self.helpPanel.SetSizer(sizer)
        self.helpPanel.Hide()
        self.helpPanel.Raise()
        self.helpPanel.SetBackgroundColour((240,250,240))
        self.Bind(wx.EVT_SIZE, self._onSize)

        self._onShowCntrls(None)

    def _onShowHelp(self, event):
        self.helpPanel.SetPosition((0,0))
        self.helpPanel.Show()
        self.cntrlPanel.Hide()

    def _onShowCntrls(self, event):
        self.cntrlPanel.SetPosition((0,0))
        self.helpPanel.Hide()
        self.cntrlPanel.Show()

    def _onSize(self, event):
        event.Skip()
        self.helpPanel.SetSize(self.GetClientSizeTuple())
        self.cntrlPanel.SetSize(self.GetClientSizeTuple())

app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
person Anurag Uniyal    schedule 23.06.2009
comment
Я думаю, возможно, я неправильно употребил слово наложение... Я хочу wx.Panel, который закроет основную панель wx.Panel, полностью скрывая ее. Я пробовал делать то же, что и вы, но только с wx.Panel, но как мне заставить его всегда подстраиваться под размер wx.Frame? - person Ram Rachum; 23.06.2009
comment
изначально установленная панель = размер фрейма клиента/или внутренней панели переопределяет OnSize(EVT_SIZE) и изменяет размер справки в соответствии с размером фрейма - person Anurag Uniyal; 24.06.2009
comment
хорошо, я обновил пример, так что теперь есть две панели, одна для cntrl и одна для справки, обе внутренне могут упорядочивать cntrl с помощью сайзеров, и у обеих есть кнопка для переключения на другую панель, также они изменяют размер с помощью родительского фрейма, это означает, что у него есть все тебе нужно. Но, как я уже сказал, есть несколько способов сделать это. - person Anurag Uniyal; 24.06.2009

Обновленный код для Python 3.9.4 и wxPython 4.1.1. Надеюсь, люди найдут это полезным. Первоначальный пост был полезен для меня, но мне, как новичку, потребовались некоторые усилия, чтобы он правильно работал с недавно выпущенными инструментами.

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)

        self.panel = wx.Panel(self)

        # create controls
        self.cntrlPanel = wx.Panel(self.panel)
        stc1 = wx.StaticText(self.cntrlPanel, label="wow it works")
        stc2 = wx.StaticText(self.cntrlPanel, label="yes it works")
        btn = wx.Button(self.cntrlPanel, label="help?")
        btn.Bind(wx.EVT_BUTTON, self._onShowHelp)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(stc1)
        sizer.Add(stc2)
        sizer.Add(btn)
        self.cntrlPanel.SetSizer(sizer)

        # create help panel
        self.helpPanel = wx.Panel(self.panel)
        self.stcHelp = wx.StaticText(self.helpPanel, label="help help help\n"*8)
        btn = wx.Button(self.helpPanel, label="close[x]")
        btn.Bind(wx.EVT_BUTTON, self._onShowCntrls)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.stcHelp)
        sizer.Add(btn)
        self.helpPanel.SetSizer(sizer)

        self.helpPanel.Hide()
        self.helpPanel.Raise()
        self.helpPanel.SetBackgroundColour((240,250,240))

        self.Bind(wx.EVT_SIZE, self._onSize)

        self._onShowCntrls(None)

    def _onShowHelp(self, event):
        self.helpPanel.SetPosition((0,0))
        self.helpPanel.Show()
        self.cntrlPanel.Hide()

    def _onShowCntrls(self, event):
        self.cntrlPanel.SetPosition((0,0))
        self.helpPanel.Hide()
        self.cntrlPanel.Show()

    def _onSize(self, event):
        event.Skip()
        self.helpPanel.SetSize(self.GetClientSize())
        self.cntrlPanel.SetSize(self.GetClientSize())

app = wx.App(False)
frame = MyFrame()
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
person Jonathan Marks    schedule 11.04.2021
comment
LOL, прошло более десяти лет с тех пор, как я задал этот вопрос ???? надеюсь, что другие найдут ваш код полезным - person Ram Rachum; 11.04.2021