Search code examples
pythonwxpythonwxwidgets

Calling wxSizer.Insert() hides item


I'm trying to insert a panel into a wxBoxSizer before the last element in that sizer using the following code:

sizer = event.EventObject.Parent.GetSizer()

# Add new panel from xrc        
res = xrc.XmlResource('add_panel.xrc')
panel = res.LoadPanel(self, 'panel')
sizer.Insert(len(sizer.Children) -1, panel)

sizer.Layout()

But when I run it the new panel shows correctly but the button which was previously the last element in the table is nowhere to be seen. On a couple of occasions I've seen the button partially obscured, so clearly it's still where it was before but hidden behind the new panel. Question is, having called sizer.Layout() why is it still in its old position and what am I not doing that would stop it misbehaving?


Solution

  • Your parenting is probably wrong. Some of the object's parents do not correspond to the actual structure and / or sizers. Try this sample:

    import wx
    
    class MainWindow(wx.Frame):
        def __init__(self, *args, **kwargs):
            wx.Frame.__init__(self, *args, **kwargs)
            self.panel = wx.Panel(self)
            self.button = wx.Button(self.panel, label="New")
            self.button.Bind(wx.EVT_BUTTON, self.OnButton)
            self.buttons = []
            self.sizer = wx.BoxSizer()
            self.sizer.Add(self.button)
            self.panel.SetSizerAndFit(self.sizer)
            self.Show()
    
        def OnButton(self, e):
            button = wx.Button(self.panel, label=str(len(self.buttons)))
            self.buttons.append(button)
            self.sizer.Insert(len(self.sizer.Children) - 1, button)
            self.sizer.Layout()
    
    app = wx.App(False)
    win = MainWindow(None)
    app.MainLoop()