Question

I have a separate file for main app (f.py) and separate file for a panel (p.py). I am setting a Menubar to Frame from within the Panel. Here is my working code:

f.py

import wx
import p

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Checking Menubar from external Panel")

        mainPanel = wx.Panel(self, -1)
        mainPanel.SetBackgroundColour(wx.Color(0, 255, 0))
        sizer = wx.BoxSizer(wx.VERTICAL)
        mainPanel.SetSizer(sizer)

        subPanel = p.MyPanel(parent=mainPanel)
        sizer.Add(subPanel, 1, wx.EXPAND)

#         subPanel.createMenuBar()

        self.Show()


if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = MyFrame()
    app.MainLoop()

p.py

import wx

class MyPanel(wx.Panel):
    def __init__(self, parent=None):
        wx.Panel.__init__(self, parent=parent, id=-1)
        self.SetBackgroundColour(wx.Color(255, 0, 0))

        self.createMenuBar()

    def createMenuBar(self):
        self.menuBar = wx.MenuBar()

        self.mnuFile = wx.Menu()
        self.mnuFile.Append(id=1, text="&New")
        self.mnuFile.Append(id=1, text="&Open")
        self.mnuFile.Append(id=1, text="E&xit")

        self.menuBar.Append(menu=self.mnuFile, title="&File")
        self.GetTopLevelParent().SetMenuBar(self.menuBar)

Above code adds a Menubar to Frame. But the Panel is not getting full size on output window. Here is the output image:

<code>Panel</code> not getting full size

Now, if I call createMenu function of Panel from within Frame (by uncommenting subPanel.createMenuBar() line from f.py and commenting self.createMenuBar() line from p.py) it gives output as desired. Here is the output image in which Panel covers full Frame:

<code>Panel</code> covers full <code>Frame</code>

I am not able to understand the reason why setting Menubar from within Panel disturbs the size of it. Any help is appreciated.

Était-ce utile?

La solution

You just need to to call Layout() on your sizer object:

import wx
import p

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Checking Menubar from external Panel")

        mainPanel = wx.Panel(self, -1)
        mainPanel.SetBackgroundColour(wx.Color(0, 255, 0))
        sizer = wx.BoxSizer(wx.VERTICAL)
        mainPanel.SetSizer(sizer)

        subPanel = p.MyPanel(parent=mainPanel)
        sizer.Add(subPanel, 1, wx.EXPAND)

#         subPanel.createMenuBar()

        self.Show()
        sizer.Layout()


if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

Personally, I don't really see a reason to add a single panel on top of another panel. That just adds unneeded complexity. Here's a shorter version:

import wx
import p

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Checking Menubar from external Panel")

        sizer = wx.BoxSizer(wx.VERTICAL)

        mainPanel = p.MyPanel(parent=self)
        sizer.Add(mainPanel, 1, wx.EXPAND)
        self.SetSizer(sizer)

        self.Show()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

You will note that I don't need to even call Layout() on this second version because theirs only one panel and it automatically takes up all the space. Also note that I changed your call from wx.PySimpleApp to wx.App(False). PySimpleApp is deprecated.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top