WxPython, How to implement paging functionality for wx.grid.Grid?

Question:

I want to load a csv file with (10 cols, 1 000 000 rows), on to wx.Grid with row autosizing.
The time taken to auto size 1 million rows is too much (>1 hour depending on data).

So I want to implement paging functionality to wx.Grid.

Ideas I have in mind:

1: Using wx.grid vertical scrollbar

  1. Initially Load 1000 rows of data with autosize.
  2. To catch wx.grid vertical scrollbar event when reached end of grid, the append another 1000 rows to grid.

2: Using menu option or buttons

  1. Create menu options or button in parent Wx.Frame with names as Prev, Next keeping them disabled.
  2. Then load wx.grid on Wx.Frame with only 1000 rows of data with autosize, and enable Prev, Next options.
  3. Whenever user presses any option, clear data on grid, and add next 1000 rows of data.

Code for 1:
Created empty sample grid without data.
Trying to use scrollbar scrolled bottom event to trigger AddRows function:
(But it’s not working with any scroll bar events, I tried)

import wx
import wx.grid

class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="A Simple Grid")

        panel = wx.Panel(self)
        myGrid = MyGrid(panel)
        myGrid.fillGrid()

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

        self.Maximize()


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

    def fillGrid(self):
        self.CreateGrid(1000, 10)

        self.SetColLabelValue(0, "Column1")
        self.SetColLabelValue(1, "Column2")
        self.SetColLabelValue(2, "Column3")
        self.SetColLabelValue(3, "Column4")
        self.SetColLabelValue(4, "Column5")
        self.SetColLabelValue(5, "Column6")
        self.SetColLabelValue(6, "Column7")
        self.SetColLabelValue(7, "Column8")
        self.SetColLabelValue(8, "Column9")
        self.SetColLabelValue(9, "Column10")

        self.SetDefaultColSize(width=350, resizeExistingCols=True)
        self.SetDefaultRowSize(height=30, resizeExistingRows=True)
        
        # Any proper Scroll Bar Event to Trigger Add new rows.
        self.Bind(wx.EVT_SCROLL_BOTTOM, self.AddRows)

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


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

Summary:

I’m not able to implement any of the above ideas properly with my limited experience in WxPython.

I need an working implementation for any of above ideas of wx.grid paging.

And please suggest other possible ideas to achieve my need for paging functionality.

Versions:

  • Windows V20H2
  • Python 3.10.7
  • WxPython 4.2.0
Asked By: tarun_b

||

Answers:

To implement paging functionality to wx.Grid.
Using menu option (Page)

  1. Created menu option in parent Wx.Frame with names as "Page", Sub Menu "Next".
  2. Initialized wx.grid on Wx.Frame with only 25000 rows of data with default col size.
  3. Whenever user presses Next Menu button, code appends next 10000 rows of empty data.

Code for 2nd Idea:

# This python code is to load grid using paging functionality via Menu Option
# New Menu Option Page is created with SubMenu "Next (Ctrl + N)"
# Initially when triggering Grid, Loads only 25000 rows
# When clicked on next button in Page Menu, it loads another 10000 rows
import wx
import wx.grid


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Grid Paging via Menu Option")

        menubar = wx.MenuBar()
        page_menu = wx.Menu()
        menubar.Append(page_menu, "Page")
        next_item = wx.MenuItem(page_menu, wx.ID_EXIT, '&NexttCtrl+N')
        page_menu.Append(next_item)
        self.Bind(wx.EVT_MENU, self.loadNextCells, next_item)

        panel = wx.Panel(self)
        self.myGrid = MyGrid(panel)
        self.myGrid.fillGrid()

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

        self.SetMenuBar(menubar)
        self.Maximize()

    def loadNextCells(self, e):
        MyGrid.AddRows(self.myGrid)


class MyGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, style=wx.HSCROLL | wx.VSCROLL)
        self.rowCount = None

    def fillGrid(self):
        self.CreateGrid(25000, 7)
        self.SetDefaultColSize(width=350, resizeExistingCols=True)
        self.SetSelectionMode(selmode=self.GridSelectRows)

    def AddRows(self):
        self.AppendRows(10000, True)


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()
Answered By: tarun_b
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.