pythonwxpythonwxgrid

wxPython Displaying Grid in BoxSizer


I am trying to display a grid along with some button for navigating through my table on a wx.Panel using wx.Boxsizer. I can get the grid and the buttons to show correctly if I add the buttons first to the BoxSizer where the buttons are on top of the grid in a vertical layout. If I switch the order around where the grid is on top of the buttons in a vertical layout, the buttons will not display the grid will take up the entire panel.

works:

    self.sizer.AddSpacer(10)
    self.sizer.Add(self.bottomBtnsPnl,1,wx.EXPAND)
    self.sizer.AddSpacer(10)
    self.sizer.Add(self.gridPnl,1,wx.EXPAND)
    self.sizer.AddSpacer(10)

does not work:

    self.sizer.AddSpacer(10)
    self.sizer.Add(self.gridPnl,1,wx.EXPAND)
    self.sizer.AddSpacer(10)
    self.sizer.Add(self.bottomBtnsPnl,1,wx.EXPAND)
    self.sizer.AddSpacer(10)

all my code: TableView.py:

import wx
from TFMtable import TFMemployeeGridTable

class TableView(wx.Panel):
    def __init__(self, parent, ID, db):
        wx.Panel.__init__(self, parent, ID)
        self.sizer = wx.BoxSizer(wx.VERTICAL)

        self.gridPnl = wx.Panel(self,1)
        self.gridPnlSizer = wx.BoxSizer(wx.VERTICAL)

        if db.getTFMemployeeRowCount() >= 100:
            self.TFMemployeeGrid = TFMemployeeGridTable(self.gridPnl, gridRows=db.getTFMemployeeRowCount(), rows=db.getTFMemployee100Rows(0,100))
        else:
            self.TFMemployeeGrid = TFMemployeeGridTable(self.gridPnl, gridRows=db.getTFMemployeeRowCount(), rows=db.getTFMemployee100Rows(0,db.getTFMemployeeRowCount()))

        self.gridPnlSizer.Add(self.TFMemployeeGrid,1,wx.EXPAND)


        self.gridPnl.SetAutoLayout(True)
        self.gridPnl.SetSizer(self.gridPnlSizer)
        self.gridPnlSizer.Fit(self.gridPnl)


        self.bottomBtnsPnl = wx.Panel(self,1)
        self.bottomSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.beginningBtn =wx.Button(self.bottomBtnsPnl, 0, label='<<')
        self.backBtn =wx.Button(self.bottomBtnsPnl, 0, label='<')
        self.editBtn =wx.Button(self.bottomBtnsPnl, 0, label='Edit')
        self.nextBtn =wx.Button(self.bottomBtnsPnl, 0, label='>')
        self.lastBtn =wx.Button(self.bottomBtnsPnl, 0, label='>>')

        self.bottomSizer.AddStretchSpacer()
        self.bottomSizer.Add(self.beginningBtn,0,wx.EXPAND)
        self.bottomSizer.AddSpacer(10)
        self.bottomSizer.Add(self.backBtn,0,wx.EXPAND)
        self.bottomSizer.AddSpacer(10)
        self.bottomSizer.Add(self.editBtn,0,wx.EXPAND)
        self.bottomSizer.AddSpacer(10)
        self.bottomSizer.Add(self.nextBtn,0,wx.EXPAND)
        self.bottomSizer.AddSpacer(10)
        self.bottomSizer.Add(self.lastBtn,0,wx.EXPAND)
        self.bottomSizer.AddStretchSpacer()


        self.bottomBtnsPnl.SetAutoLayout(True)
        self.bottomBtnsPnl.SetSizer(self.bottomSizer)
        self.bottomSizer.Fit(self.bottomBtnsPnl)


        self.sizer.AddSpacer(10)
        self.sizer.Add(self.gridPnl,1,wx.EXPAND)
        self.sizer.AddSpacer(10)
        self.sizer.Add(self.bottomBtnsPnl,1,wx.EXPAND)
        self.sizer.AddSpacer(10)

        self.SetAutoLayout(True)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)

TFMtable.py:

import wx
import wx.grid

class TFMemployeeGridTable(wx.grid.Grid):
    def __init__(self, parent, gridRows, rows):

        wx.grid.Grid.__init__(self, parent)
        self.CreateGrid(100,7)
        self.SetColLabelValue(0, "ID")
        self.SetColLabelValue(1, "employeeNumber")
        self.SetColLabelValue(2, "RoomNum")
        self.SetColLabelValue(3, "Last")
        self.SetColLabelValue(4, "First")
        self.SetColLabelValue(5, "Wage")
        self.SetColLabelValue(6, "DateStated")

        row = 0
        for items in rows:
            if row==0:
                self.SetCellValue(row,0,str(items[0]))
                self.SetCellBackgroundColour(row, 0, wx.LIGHT_GREY)
                self.SetCellValue(row,1,str(items[1]))
                self.SetCellBackgroundColour(row, 1, wx.LIGHT_GREY)
                self.SetCellValue(row,2,str(items[2]))
                self.SetCellBackgroundColour(row, 2, wx.LIGHT_GREY)
                self.SetCellValue(row,3,str(items[3]))
                self.SetCellBackgroundColour(row, 3, wx.LIGHT_GREY)
                self.SetCellValue(row,4,str(items[4]))
                self.SetCellBackgroundColour(row, 4, wx.LIGHT_GREY)
                self.SetCellValue(row,5,str(items[5]))
                self.SetCellBackgroundColour(row, 5, wx.LIGHT_GREY)
                self.SetCellValue(row,6,str(items[6]))
                self.SetCellBackgroundColour(row, 6, wx.LIGHT_GREY)
            elif row%2==0:
                self.SetCellValue(row,0,str(items[0]))
                self.SetCellBackgroundColour(row, 0, wx.LIGHT_GREY)
                self.SetCellValue(row,1,str(items[1]))
                self.SetCellBackgroundColour(row, 1, wx.LIGHT_GREY)
                self.SetCellValue(row,2,str(items[2]))
                self.SetCellBackgroundColour(row, 2, wx.LIGHT_GREY)
                self.SetCellValue(row,3,str(items[3]))
                self.SetCellBackgroundColour(row, 3, wx.LIGHT_GREY)
                self.SetCellValue(row,4,str(items[4]))
                self.SetCellBackgroundColour(row, 4, wx.LIGHT_GREY)
                self.SetCellValue(row,5,str(items[5]))
                self.SetCellBackgroundColour(row, 5, wx.LIGHT_GREY)
                self.SetCellValue(row,6,str(items[6]))
                self.SetCellBackgroundColour(row, 6, wx.LIGHT_GREY)
            else:
                self.SetCellValue(row,0, ""+str(items[0]))
                self.SetCellTextColour(row, 0, wx.BLACK)
                self.SetCellBackgroundColour(row, 0, wx.WHITE)
                self.SetCellValue(row,1, ""+str(items[1]))
                self.SetCellTextColour(row, 1, wx.BLACK)
                self.SetCellBackgroundColour(row, 1, wx.WHITE)
                self.SetCellValue(row,2, ""+str(items[2]))
                self.SetCellTextColour(row, 2, wx.BLACK)
                self.SetCellBackgroundColour(row, 2, wx.WHITE)
                self.SetCellValue(row,3, ""+str(items[3]))
                self.SetCellTextColour(row, 3, wx.BLACK)
                self.SetCellBackgroundColour(row, 3, wx.WHITE)
                self.SetCellValue(row,4, ""+str(items[4]))
                self.SetCellTextColour(row, 4, wx.BLACK)
                self.SetCellBackgroundColour(row, 4, wx.WHITE)
                self.SetCellValue(row,5, ""+str(items[5]))
                self.SetCellTextColour(row, 5, wx.BLACK)
                self.SetCellBackgroundColour(row, 5, wx.WHITE)
                self.SetCellValue(row,6, ""+str(items[6]))
                self.SetCellTextColour(row, 6, wx.BLACK)
                self.SetCellBackgroundColour(row, 6, wx.WHITE)

            row = row+1

        self.SetSelectionMode(wx.grid.Grid.SelectRows)


        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.CellLeftClick, self)


    def CellLeftClick(self,e):
        print("click on grid")

Solution

  • You can self-diagnose most visual layout problems using the wxPython Widget Inspection Tool, which you can read about here:

    It will help show you how widgets overlap, what the widget's parent is, what size the widget is, etc. I also noticed that you were setting self.gridPnl's ID to 1. This is bad. IDs less than 100 are usually reserved by wxPython, which is why you will normally see the magic -1 or wx.ID_ANY in the example apps online. The -1 and wx.ID_ANY tell wxPython to dynamically create an ID that won't conflict with any other IDs that are currently in use.

    Finally, here's a super simple example that shows how to create a grid with a couple of buttons underneath it:

    import wx
    import wx.grid as gridlib
    
    ########################################################################
    class MyForm(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, parent=None, title="A Simple Grid")
            panel = wx.Panel(self)
    
            myGrid = gridlib.Grid(panel)
            myGrid.CreateGrid(12, 8)
    
            btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
            btn_one = wx.Button(panel, label="One")
            btn_sizer.Add(btn_one, 0, wx.CENTER|wx.ALL, 5)
    
            btn_two = wx.Button(panel, label="Two")
            btn_sizer.Add(btn_two, 0, wx.CENTER|wx.ALL, 5)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(myGrid, 1, wx.EXPAND)
            sizer.Add(btn_sizer)
            panel.SetSizer(sizer)
    
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyForm()
        frame.Show()
        app.MainLoop()