Dynamically replace a wxPanel object

Hi,

I want to replace a existing wxPanel object with a new one.
The code below seems to work. However, the new panel is not shown
until I resize the window.

I use wxPython2.4 on Windows2000

···

#----------------------------------------------------------------------
# A very simple wxPython example. Just a wxFrame, wxPanel,
# wxStaticText, wxButton, and a wxBoxSizer, but it shows the basic
# structure of any wxPython application.
#----------------------------------------------------------------------

from wxPython.wx import *

class MyFrame(wxFrame):
    """
    This is MyFrame. It just shows a few controls on a wxPanel,
    and has a simple menu.
    """
    def __init__(self, parent, title):
        wxFrame.__init__(self, parent, -1, title, size=(350, 200))

        menuBar = wxMenuBar()
        menu = wxMenu()
        menu.Append(101, "E&xit\tAlt-X", "Exit demo")
        EVT_MENU(self, 101, self.OnButton)
        menuBar.Append(menu, "&File")
        self.SetMenuBar(menuBar)

        self.Panel1()

    def Panel1(self):
        panel = wxPanel(self, -1)
        text = wxStaticText(panel, -1, "Hello World!")
        text.SetFont(wxFont(12, wxSWISS, wxNORMAL, wxBOLD))
        text.SetSize(text.GetBestSize())
        btn = wxButton(panel, -1, "Panel2")
        btn.SetDefault()

        sizer = wxBoxSizer(wxVERTICAL)
        sizer.Add(text, 0, wxALL, 10)
        sizer.Add(btn, 0, wxALL, 10)
        panel.SetSizer(sizer)
        panel.SetAutoLayout(True)
        panel.Layout()

        EVT_BUTTON(self, btn.GetId(), self.OnButton1)
        self.panel1 = panel

    def OnButton1(self, evt):
        """Event handler for the button click."""
        print "OnButton1"
        self.panel1.Destroy()
        self.Panel2()

    def Panel2(self):
        panel = wxPanel(self, -1)
        text = wxStaticText(panel, -1, "Hello again!")
        text.SetFont(wxFont(12, wxSWISS, wxNORMAL, wxBOLD))
        text.SetSize(text.GetBestSize())
        btn = wxButton(panel, -1, "Close")
        btn.SetDefault()

        sizer = wxBoxSizer(wxVERTICAL)
        sizer.Add(text, 0, wxALL, 10)
        sizer.Add(btn, 0, wxALL, 10)
        panel.SetSizer(sizer)
        panel.SetAutoLayout(True)
        panel.Layout()

        EVT_BUTTON(self, btn.GetId(), self.OnButton)

        # what should I do here to show the new panel???
        # The calls below did not work.
        #self.Refresh()
        #self.Update()
        #wxSafeYield()
        #panel.Show()

    def OnButton(self, evt):
        """Event handler for the button click."""
        print "OnButton"
        self.Close()

app = wxPySimpleApp()
frame = MyFrame(None, "Simple wxPython App")
frame.Show(True)
app.MainLoop()

--
  Stefan.

I want to replace a existing wxPanel object with a new one.
The code below seems to work. However, the new panel is not shown
until I resize the window.

...

    def Panel2(self):

You need to add a size to the panel when it is created:

        panel = wxPanel(self, -1,size=self.GetClientSize())

By default, a single child window is automatically sized to fill the client
area of a window when the window is resized, which happens when you create
the first panel because the frame is being created at the same time so the
first panel was resized and visible. The second one was also created with a
size of (0,0) but the frame was not being resized at that point so the panel
didn't become visible until the frame was manually resized.

-Rick King
Southfield MI

Stefan Reichvr wrote:

Hi,

I want to replace a existing wxPanel object with a new one.
The code below seems to work. However, the new panel is not shown
until I resize the window.

   def OnButton1(self, evt):
       """Event handler for the button click."""
       print "OnButton1"
       self.panel1.Destroy()
       self.Panel2()

At the end of this event handler, try adding a call to self.Layout().

You're creating your panels without giving them a size. This is fine for the first one, because it receives a size event when the frame is first created (and, with the panel being the only child of the frame, it's automatically sized to fill the frame). The second panel, however, is created *after* the frame, so it doesn't get that initial size event. You need to force a size event to happen; calling the frame's Layout() method should accomplish that.

Jeff Shannon
Technician/Programmer
Credit International