pythonpaginationgridwxpythonwxgrid

How to add new rows to wxpython grid, when vertical progress bar is scrolled to the end of grid


At the launch of the program I want to load Wx.Grid with 5 cols and 1000 rows. And, I want to append 1000 rows again, when vertical scrollbar of wx.grid is scrolled to end of grid.

So, I'm trying to catch wx.grid vertical scrollbar event when reached end of grid, and call append rows function.

But, none of the scrollbar events are working for me.!

Versions I'm using:

Problem code: For an empty grid with 5 cols and 1000 rows, I'm trying to add 1000 more empty rows, when scrollbar reaches end of grid.

import wx
import wx.grid


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="To Append Rows")

        panel = wx.Panel(self)

        global myGrid
        myGrid = wx.grid.Grid(panel)
        myGrid.CreateGrid(1000, 5)

        myGrid.SetColLabelValue(0, "Column1")
        myGrid.SetColLabelValue(1, "Column2")
        myGrid.SetColLabelValue(2, "Column3")
        myGrid.SetColLabelValue(3, "Column4")
        myGrid.SetColLabelValue(4, "Column5")

        myGrid.SetDefaultColSize(width=500, resizeExistingCols=True)
        myGrid.SetDefaultRowSize(height=30, resizeExistingRows=True)

        # None the below events work to catch a scroll bar event and trigger append rows.
        myGrid.Bind(wx.EVT_SCROLL_BOTTOM, self.AddRows)
        myGrid.Bind(wx.EVT_SCROLL_ENDSCROLL, self.AddRows)
        myGrid.Bind(wx.EVT_SCROLL, self.AddRows)
        myGrid.Bind(wx.EVT_SCROLLBAR, self.AddRows)
        myGrid.Bind(wx.EVT_SCROLL_PAGEDOWN, self.AddRows)
        myGrid.Bind(wx.EVT_SCROLLWIN_BOTTOM, self.AddRows)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(myGrid, 1, wx.EXPAND)
        panel.SetSizerAndFit(sizer)

        self.Maximize()

    def AddRows(self, event):
        print(event.GetEventObject())
        myGrid.AppendRows(1000, True)


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


Solution

  • Using only wx.grid.Grid without wx.grid.GridTableBase you'll need to keep track of how many rows are in the table, manually (I think).

    You are currently using wx.EVT_SCROLL events these are for stand-alone scrollbars. You should use wx.ScrollWinEvent.

    The following should inch you closer to your goal. I've tracked the Down and Page Down keys as well, in case of keyboard input and set the last row manually at the start.

    Here, set as the 99th row and subsequently 199th, 299th etc

    import wx
    import wx.grid
    
    
    class MyForm(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, parent=None, title="To Append Rows")
    
            panel = wx.Panel(self)
    
            self.myGrid = wx.grid.Grid(panel)
            self.myGrid.CreateGrid(100, 5)
            self.lastrow = 98
            self.myGrid.SetColLabelValue(0, "Column1")
            self.myGrid.SetColLabelValue(1, "Column2")
            self.myGrid.SetColLabelValue(2, "Column3")
            self.myGrid.SetColLabelValue(3, "Column4")
            self.myGrid.SetColLabelValue(4, "Column5")
    
            self.myGrid.SetDefaultColSize(width=100, resizeExistingCols=True)
            self.myGrid.SetDefaultRowSize(height=30, resizeExistingRows=True)
    
            self.myGrid.Bind(wx.EVT_SCROLLWIN, self.AddRows)
            self.myGrid.Bind(wx.EVT_KEY_DOWN, self.OnKey)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.myGrid, 1, wx.EXPAND)
            panel.SetSizer(sizer)
    
            #self.Maximize()
    
        def AddRows(self, event):
            if self.myGrid.IsVisible(self.lastrow, 0):
                self.myGrid.AppendRows(100, True)
                self.lastrow += 100
                self.Refresh()
                print("Rows Added")
            if event:
                event.Skip()
    
        def OnKey(self, event):
            keycode = event.GetKeyCode()
            if keycode == wx.WXK_DOWN or keycode == wx.WXK_PAGEDOWN:
                self.AddRows(None)
            event.Skip()
    
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyForm().Show()
        app.MainLoop()
    

    Hopefully, someone who uses wx.grid in anger will post a better answer.