Ahmad313
Ahmad313

Reputation: 57

How to prevent wx panels from overlapping on other sizers

Basically I am trying to accomplish a simple hide panel and show another on button click, I usually am able to do those if I have a single sizer in the frame but in this case I have a ribbon so I have 2 sizers in the frame and whenever I show a panel in sizer 2 it overlaps and shows as if it doesn't belong to a sizer.

I drafted a basic colored example to reproduce the issue, notice that when you click the button the blue panel hides the yellow one instead of replacing the grey one.

import wx


class MyForm(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "HomeFinance", size = (1400,700))
        self.panel1 = RibbonPanel(self)
        self.panel2 = SidePanel(self)
        self.panel3 = MainPanel(self)
        self.panel4 = NewPanel(self)

        self.panel1.SetBackgroundColour(wx.Colour(191, 193, 65))
        self.panel2.SetBackgroundColour(wx.Colour(56, 122, 45))
        self.panel3.SetBackgroundColour(wx.Colour(77, 84, 96, 0))
        self.panel4.SetBackgroundColour(wx.Colour(55, 149, 153, 0))
        self.panel4.Hide()

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.hsizer = wx.BoxSizer(wx.HORIZONTAL)

        self.sizer.Add(self.panel1, 1, wx.EXPAND)
        self.hsizer.Add(self.panel4, 1, wx.EXPAND)
        self.hsizer.Add(self.panel3, 1, wx.EXPAND)
        self.hsizer.Add(self.panel2, 1, wx.EXPAND)
        self.sizer.Add(self.hsizer, 1, wx.EXPAND)

        self.Bind(wx.EVT_BUTTON, self.onetimer, self.panel2.m_button1)
        self.SetSizer(self.sizer)
        self.CenterOnScreen()
        self.Show()

    def onetimer(self, event):
        self.panel3.Hide()
        self.panel4.Show()


class RibbonPanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1400, 115), style=wx.TAB_TRAVERSAL,
                 name=wx.EmptyString):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style, name=name)
        self.Layout()

class MainPanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1000, 545), style=wx.TAB_TRAVERSAL,
                 name=wx.EmptyString):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style, name=name)
        self.Layout()


class SidePanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(400, 545), style=wx.TAB_TRAVERSAL,
                 name=wx.EmptyString):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style, name=name)
        self.m_button1 = wx.Button(self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0)
        self.Layout()


class NewPanel(wx.Panel):
    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(1000, 545), style=wx.TAB_TRAVERSAL,
                 name=wx.EmptyString):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style, name=name)
        self.Layout()

# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

The blue panel is expected to replace the grey one and have the exact same spot.

Upvotes: 1

Views: 184

Answers (1)

kbr85
kbr85

Reputation: 1436

When you change the widgets being displayed you need the sizer to calculate the new positions and sizes. Therefore, your code was only missing a call to self.Layout() in onetimer

The method should be:

def onetimer(self, event):
    self.panel3.Hide()
    self.panel4.Show()
    self.Layout()

Upvotes: 1

Related Questions