Search code examples
pythonwxpython

Multiple panels


I'm having two problems with my program. The code below generates two panels when it should generate 3. It generates panel1 and panel2 no problem but panel3 should be to the right of panel2 is no where to be seen. Panel1 and panel2 are split vertically I'm trying to do the same with panel2 and panel3

My second problem is how do I generate another panel below panel1 without disrupting the splitter between panel1 and panel2 and then create a splitter between panel1 and new created panel below it?

import wx


class Panels(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        splitter = wx.SplitterWindow(self, -1)

        vbox1 = wx.BoxSizer(wx.VERTICAL)
        panel1 = wx.Panel(splitter, -1)
        panel12 = wx.Panel(panel1, -1, style=wx.BORDER_SUNKEN)
        st1 = wx.StaticText(panel12, -1, 'Panel 1', (5, 5))
        vbox1.Add(panel12, 1, wx.EXPAND)
        panel1.SetSizer(vbox1)

        vbox2 = wx.BoxSizer(wx.VERTICAL)
        panel2 = wx.Panel(splitter, -1)
        panel22 = wx.Panel(panel2, -1, style=wx.BORDER_RAISED)
        st2 = wx.StaticText(panel22, -1, 'Panel 2', (5, 5))
        vbox2.Add(panel22, 1, wx.EXPAND)
        panel2.SetSizer(vbox2)

        vbox3 = wx.BoxSizer(wx.VERTICAL)
        panel3 = wx.Panel(splitter, -1)
        panel32 = wx.Panel(panel3, -1, style=wx.BORDER_RAISED)
        st3 = wx.StaticText(panel32, -1, 'Panel 3', (5, 5))
        vbox3.Add(panel32, 1, wx.EXPAND)
        panel3.SetSizer(vbox3)

        hbox.Add(splitter, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
        self.SetSizer(hbox)
        self.CreateStatusBar()
        splitter.SplitVertically(panel1, panel3)
        splitter.SplitVertically(panel2, panel3)
        self.Centre()
        self.Show(True)


    def ExitApp(self, event):
        self.Close()


app = wx.App()
Panels(None, -1, 'Panels')
app.MainLoop()

Solution

  • You have a couple options. You could nest your SplitterWindows, which is kind of confusing, but effective. Or you could use the MultiSplitterWindow widget.

    For the first one, I'd do something like this:

    1. Create a main splitter and a sub-splitter
    2. In the sub-splitter, but the first two panels
    3. Put the sub-splitter and the 3rd panel in the main splitter

    Or some variation thereof.

    EDIT: Here's one example:

    import wx
    
    ########################################################################
    class RandomPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent, color):
            """Constructor"""
            wx.Panel.__init__(self, parent)
            self.SetBackgroundColour(color)
    
    
    
    ########################################################################
    class MainPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)
    
            topSplitter = wx.SplitterWindow(self)
            hSplitter = wx.SplitterWindow(topSplitter)
    
            panelOne = RandomPanel(hSplitter, "blue")
            panelTwo = RandomPanel(hSplitter, "red")
            hSplitter.SplitVertically(panelOne, panelTwo)
            hSplitter.SetSashGravity(0.5)
    
            panelThree = RandomPanel(topSplitter, "green")
            topSplitter.SplitHorizontally(hSplitter, panelThree)
            topSplitter.SetSashGravity(0.5)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(topSplitter, 1, wx.EXPAND)
            self.SetSizer(sizer)
    
    ########################################################################
    class MainFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, title="Nested Splitters",
                              size=(800,600))
            panel = MainPanel(self)
            self.Show()
    
    #----------------------------------------------------------------------
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MainFrame()
        app.MainLoop()
    

    See also might want to look at wx.SashLayoutWindow: http://www.wxpython.org/docs/api/wx.SashLayoutWindow-class.html