pythonpython-3.xwxpythonwxgridboxsizer

Nested sizers in three panel Grid Layout in wxpython


I am building a GUI that consists of three panels and 2 grids(one grid in each panel). I am struggling with getting objects into their respective panels using the BoxSizer. It seems that the vertical boxsizer is only taking into account the upper and lower portions of the frame and not taking into account that the upper portion is a split into two panels. Therefore I am having a problem trying to organize widgets vertically in the upper portion. When trying to add widgets to panelTwo, the vertical placement picks up from panelOne or vice versa. I would like to have a vertical boxsizer assigned to each panel if possible. Please excuse the sloppy code. I am only a few days into Python so take it easy on me! I am open to suggestions! Here is the section I am having trouble with:

    p1Sizer = wx.BoxSizer(wx.VERTICAL)
    p2Sizer = wx.BoxSizer(wx.VERTICAL)
    p3Sizer = wx.BoxSizer(wx.VERTICAL)`


    p3Sizer.Add(bottom_grid, 1, wx.EXPAND)#,pos=(200,200)

    p2Sizer.Add(p1Sizer)
    hbox1.Add(st1, flag=wx.ALL, border=5)
    hbox1.Add(tc1, flag=wx.ALL, border=10)
    hbox2.Add(st2, flag=wx.ALL, border=5)
    hbox2.Add(tc2, flag=wx.ALL, border=10)
    hbox3.Add(st3, flag=wx.ALL, border=5)
    hbox3.Add(tc3, flag=wx.ALL, border=5)
    p1Sizer.Add(hbox1,flag=wx.ALIGN_RIGHT)
    p1Sizer.Add(hbox2, flag=wx.ALIGN_RIGHT)
    p1Sizer.Add(hbox3, flag=wx.ALIGN_LEFT)

If I include this line, panelTwo is formatted correctly. The only change is that the bottom box needs to be moved down. See attachments.

p2Sizer.Add(0,-120)

Line Added

If I remove that line:

Line removed

But I feel that this is not the proper way to do this. I am also trying to find a way to create two separate grids with different amount of rows. i.e

self.CreateGrid(100, 27)

and...

'self.CreateGrid(5, 27)'

import wx import wx.grid as gridlib import pandas as pd import numpy as np

class MyGrid(gridlib.Grid): def __init__(self, parent):

    """Constructor"""
    gridlib.Grid.__init__(self, parent)

    self.CreateGrid(100, 27)         

class MasterPanel(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)
    vSplitter = wx.SplitterWindow(topSplitter)
    font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)

    font.SetPointSize(50)

    panelOne = MasterPanel(vSplitter, "light grey")
    panelTwo = MasterPanel(vSplitter, "white")
    panelThree = MasterPanel(topSplitter,"white")

    vSplitter.SplitVertically(panelOne, panelTwo)
    vSplitter.SetMinimumPaneSize(300) # 300

    vSplitter.SetSashGravity(.5)


    topSplitter.SplitHorizontally(vSplitter, panelThree)
    topSplitter.SetMinimumPaneSize(200) #200
    topSplitter.SetSashGravity(1)
    #topSplitter.SetSashGravity(1)

# Assign grid to BOTTOM PANEL bottom_grid = MyGrid(panelThree) top_grid= MyGrid(panelTwo)

    st1 = wx.StaticText(panelOne, -1,"Name")
    st1.SetFont(font)
    st2 = wx.StaticText(panelOne, -1,"Date:")    
    st2.SetFont(font)
    st3 = wx.StaticText(panelOne, -1,"Input #:")
    st3.SetFont(font)
    st4 = wx.StaticText(panelTwo, -1,"From Source:")
    st4.SetFont(font)
    st5 = wx.StaticText(panelTwo, -1,"Lookup:")
    st5.SetFont(font)
    st6 = wx.StaticText(panelTwo, -1,"Lookup Value:")
    st6.SetFont(font)

    tc1 = wx.TextCtrl(panelOne,size=(150,25), value="-enter name-")
    tc2 = wx.TextCtrl(panelOne,size=(150,25), value="-enter date-")
    tc3 = wx.TextCtrl(panelOne, value="-input item #'")
    tc4 = wx.TextCtrl(panelTwo, value="-Search-")

    options= ['A','B','C']

    combo1 = wx.ComboBox(panelTwo,size=(150,25),value="-Choose Source-",choices=options, 
    style=wx.LB_SINGLE)
    combo2 = wx.ComboBox(panelTwo,size=(150,25),value="-Choose Lookup Type-",choices=options, 
    style=wx.LB_SINGLE)

    hbox1 = wx.BoxSizer(wx.HORIZONTAL)
    hbox2 = wx.BoxSizer(wx.HORIZONTAL)
    hbox3 = wx.BoxSizer(wx.HORIZONTAL)
    hbox4 = wx.BoxSizer(wx.HORIZONTAL)
    hbox5 = wx.BoxSizer(wx.HORIZONTAL)
    hbox6 = wx.BoxSizer(wx.HORIZONTAL)

    p1Sizer = wx.BoxSizer(wx.VERTICAL)
    p2Sizer = wx.BoxSizer(wx.VERTICAL)
    p3Sizer = wx.BoxSizer(wx.VERTICAL)


    p3Sizer.Add(bottom_grid, 1, wx.EXPAND)#,pos=(200,200)

    p2Sizer.Add(p1Sizer)
    hbox1.Add(st1, flag=wx.ALL, border=5)
    hbox1.Add(tc1, flag=wx.ALL, border=10)
    hbox2.Add(st2, flag=wx.ALL, border=5)
    hbox2.Add(tc2, flag=wx.ALL, border=10)
    hbox3.Add(st3, flag=wx.ALL, border=5)
    hbox3.Add(tc3, flag=wx.ALL, border=5)
    p1Sizer.Add(hbox1,flag=wx.ALIGN_RIGHT)
    p1Sizer.Add(hbox2, flag=wx.ALIGN_RIGHT)
    p1Sizer.Add(hbox3, flag=wx.ALIGN_LEFT)


    #p2Sizer.Add(0,-120)

    hbox4.Add(st4, flag=wx.ALL, border=5)
    hbox4.Add(combo1, flag=wx.ALL, border=5)
    hbox5.Add(st5, flag=wx.ALL, border=5)
    hbox5.Add(combo2, flag=wx.ALL, border=5)
    hbox6.Add(st6, flag=wx.ALL, border=5)
    hbox6.Add(tc4, flag=wx.ALL, border=5)
    p2Sizer.Add(hbox4)
    p2Sizer.Add(hbox5)
    p2Sizer.Add(hbox6)




    #p1Sizer.Add(p1, 2, wx.EXPAND)#,pos=(200,200)
    p2Sizer.Add(top_grid, 1, wx.EXPAND)#,pos=(200,200)


    panelThree.SetSizer(p3Sizer)
    panelTwo.SetSizer(p2Sizer)
    #panelOne.SetSizer(p1Sizer)

    sizer = wx.BoxSizer(wx.VERTICAL)

    #sizer.Add(top_grid)
    sizer.Add(topSplitter, -1, wx.EXPAND)

    #panelTwo.SetSizer(sizer)
    self.SetSizer(sizer)

class MainFrame(wx.Frame):

def __init__(self):
    """Constructor"""
    wx.Frame.__init__(self, None, title="Hell Yeah",
                      size=(1600,700))
    panel = MainPanel(self)
    self.Show()   `

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


Solution

  • I've "interpreted" your image, dumping the split windows, which add nothing but complication. I also dumped the font size.
    Feel free to use the code below as a starting point and re-instate them if they are essential.

    Update: after OP amended the question's image

    It's just a matter of dividing the layout into boxes. In this case and the addition of the extra grid in the question image, it's just some more virtual boxes that are required. (I choose to split p2 into p21 and p22, then place them into p2. The only reason this is necessary to to correctly align the 3 selection widgets and their text)
    I limit the size of the top grid with top_grid.SetMaxSize((-1,80))

    import wx
    import wx.grid as gridlib
    
    class MyGrid(gridlib.Grid):
        def __init__(self, parent):
            """Constructor"""
            gridlib.Grid.__init__(self, parent)
    
            self.CreateGrid(100, 27)
    
    class MasterPanel(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)
    
            font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
    
            panelOne = MasterPanel(self, "light grey")
            panelTwo = MasterPanel(self, "white")
            panelThree = MasterPanel(self,"white")
    
        # Assign grid to BOTTOM PANEL
            bottom_grid = MyGrid(panelThree)
            top_grid = MyGrid(panelTwo)
            top_grid.SetMaxSize((-1,80))
    
            st1 = wx.StaticText(panelOne, -1,"Name")
            st1.SetFont(font)
            st2 = wx.StaticText(panelOne, -1,"Date:")
            st2.SetFont(font)
            st3 = wx.StaticText(panelOne, -1,"Input #:")
            st3.SetFont(font)
            st4 = wx.StaticText(panelTwo, -1,"From Source:")
            st4.SetFont(font)
            st5 = wx.StaticText(panelTwo, -1,"Lookup:")
            st5.SetFont(font)
            st6 = wx.StaticText(panelTwo, -1,"Lookup Value:")
            st6.SetFont(font)
    
            tc1 = wx.TextCtrl(panelOne, value="-enter name-")
            tc2 = wx.TextCtrl(panelOne, value="-enter date-")
            tc3 = wx.TextCtrl(panelOne, value="-input item #'")
            tc4 = wx.TextCtrl(panelTwo, value="-Search-")
    
            options= ['Option 1','Option 2','Option 3']
    
            combo1 = wx.ComboBox(panelTwo,value="-Choose Source-",choices=options,
            style=wx.LB_SINGLE)
            combo2 = wx.ComboBox(panelTwo,value="-Choose Lookup Type-",choices=options,
            style=wx.LB_SINGLE)
    
            hbox1 = wx.BoxSizer(wx.HORIZONTAL)
            hbox2 = wx.BoxSizer(wx.HORIZONTAL)
            hbox3 = wx.BoxSizer(wx.HORIZONTAL)
            hbox4 = wx.BoxSizer(wx.HORIZONTAL)
            hbox5 = wx.BoxSizer(wx.HORIZONTAL)
            hbox6 = wx.BoxSizer(wx.HORIZONTAL)
            hbox7 = wx.BoxSizer(wx.HORIZONTAL)
    
            p1Sizer = wx.BoxSizer(wx.VERTICAL)
            p2Sizer = wx.BoxSizer(wx.VERTICAL)
            p21Sizer = wx.BoxSizer(wx.VERTICAL)
            p22Sizer = wx.BoxSizer(wx.VERTICAL)
            p3Sizer = wx.BoxSizer(wx.VERTICAL)
            p4Sizer = wx.BoxSizer(wx.VERTICAL)
            p3Sizer.Add(bottom_grid, 1, wx.EXPAND)
    
            hbox1.Add(st1, flag=wx.ALL, border=5)
            hbox1.Add(tc1, flag=wx.ALL, border=5)
            hbox2.Add(st2, flag=wx.ALL, border=5)
            hbox2.Add(tc2, flag=wx.ALL, border=5)
            hbox3.Add(st3, flag=wx.ALL, border=5)
            hbox3.Add(tc3, flag=wx.ALL, border=5)
            p1Sizer.Add(hbox1, flag=wx.ALIGN_RIGHT)
            p1Sizer.Add(hbox2, flag=wx.ALIGN_RIGHT)
            p1Sizer.Add(hbox3, flag=wx.ALIGN_RIGHT)
    
            hbox4.Add(st4, flag=wx.ALL, border=5)
            hbox4.Add(combo1, flag=wx.ALL, border=5)
            hbox5.Add(st5, flag=wx.ALL, border=5)
            hbox5.Add(combo2, flag=wx.ALL, border=5)
            hbox6.Add(st6, flag=wx.ALL, border=5)
            hbox6.Add(tc4, flag=wx.ALL, border=5)
            hbox7.Add(top_grid, flag=wx.ALL, border=5)
            p21Sizer.Add(hbox4, flag=wx.ALIGN_RIGHT)
            p21Sizer.Add(hbox5, flag=wx.ALIGN_RIGHT)
            p21Sizer.Add(hbox6, flag=wx.ALIGN_RIGHT)
            p22Sizer.Add(hbox7)
    
            p2Sizer.Add(p21Sizer)
            p2Sizer.Add(p22Sizer)
    
            panelThree.SetSizer(p3Sizer)
            panelTwo.SetSizer(p2Sizer)
            panelOne.SetSizer(p1Sizer)
    
            mainsizer_top = wx.BoxSizer(wx.HORIZONTAL)
            mainsizer_bottom = wx.BoxSizer(wx.VERTICAL)
            mainsizer = wx.BoxSizer(wx.VERTICAL)
    
            mainsizer_top.Add(panelOne, 0, wx.EXPAND)
            mainsizer_top.Add(panelTwo, 0,)
            mainsizer_bottom.Add(panelThree, 1, wx.EXPAND)
            mainsizer.Add(mainsizer_top, 0,)
            mainsizer.Add(mainsizer_bottom, 1, wx.EXPAND)
    
            self.SetSizer(mainsizer)
    
    class MainFrame(wx.Frame):
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, title="Hell Yeah",
                              size=(1600,700))
            panel = MainPanel(self)
            self.Show()
    
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MainFrame()
        app.MainLoop()
    

    enter image description here