1

I'm having trouble updating a wx grid after it's initially created in Python. I'm following the steps located here: http://wiki.wxpython.org/wxGrid but for some reason the grid is not being displayed correctly. The rows keep on being added and added, despite if the data grows or shrinks.

Here is the code. Clicking the refresh button re-initializes the data that the grid is supposed to display. The bug (I think) is in the function refreshGrid, but I can't figure out what is causing it!

import wx
from wxPython.wx import *
from wxPython.grid import *
import wx.grid
import wx.grid as gridlib
from wx.grid import Grid
import os
import sys

class MyForm(wx.Frame):

    def __init__(self):
        self.refreshMyData()

        #- Initialize the window:
        wx.Frame.__init__(self, None, wx.ID_ANY, "Grid with Popup Menu", size=(1100,300))

        # Add a panel so it looks correct on all platforms
        self.panel = wx.Panel(self, wx.ID_ANY)

        num_of_columns = 3
        self.grid = gridlib.Grid(self.panel)
        self.grid.CreateGrid(len(self.myDataList), num_of_columns)

        # change a couple column labels
        self.grid.SetColLabelValue(0, "Name")
        self.grid.SetColLabelValue(1, "Tag")
        self.grid.SetColLabelValue(2, "ID")

        self.refreshGrid()

        toolbar = self.CreateToolBar()

        qtool = toolbar.AddLabelTool(wx.ID_ANY, 'Refresh', wx.Bitmap(os.path.join(os.path.dirname(__file__), 'refresh.png')))
        toolbar.AddSeparator()
        self.Bind(wx.EVT_TOOL, self.refreshButton, qtool)

        toolbar.Realize()
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.grid, 1, wx.EXPAND, num_of_columns)
        self.panel.SetSizer(sizer)

    def refreshMyData(self):
        print '------------refreshing my data'
        import random
        self.myDataList = []
        for i in range(random.randrange(10)):
            self.myDataList.append({'Name':str(i), 'Tag':str(i), 'ID':str(i)})

    def refreshButton(self, event):
        self.refreshMyData()
        self.refreshGrid()

    def refreshGrid(self):
        print '\n\n\n------------refresh grid'
        #- Clear the grid:
        self.grid.ClearGrid()
        print 'Number of current rows: ' + str(self.grid.GetNumberRows())
        print 'Size of myDataList: ', len(self.myDataList)
        self.grid.BeginBatch()
        current, new, delmsg, addmsg = (len(self.myDataList), self.grid.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED)
        if new < current:
                print 'deleting rows:', current-new
                msg = wx.grid.GridTableMessage(
                        self.grid.GetTable(),
                        delmsg,
                        new,    # position
                        current-new,
                )
                self.grid.ProcessTableMessage(msg)
        elif new > current:
                print 'adding rows: ', new-current
                msg = wx.grid.GridTableMessage(
                        self.grid.GetTable(),
                        addmsg,
                        new-current
                )
                self.grid.ProcessTableMessage(msg)

        msg = wx.grid.GridTableMessage(self.grid.GetTable(), wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
        self.grid.ProcessTableMessage(msg)
        self.grid.EndBatch()

        print 'Number of current rows after data refresh and grid update: ' + str(self.grid.GetNumberRows())

        #- Populate the grid with new data:
        for i in range(len(self.myDataList)):
            self.grid.SetCellValue(i, 0, self.myDataList[i]['Name'])
            self.grid.SetCellValue(i, 1, self.myDataList[i]['Tag'])
            self.grid.SetCellValue(i, 2, self.myDataList[i]['ID'])

# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()
grayaii
  • 2,241
  • 7
  • 31
  • 47

1 Answers1

3

Dang. I figured it out. Here is the solution:

def refreshGrid(self):
    print '\n\n\n------------refresh grid'
    #- Clear the grid:
    self.grid.ClearGrid()
    print 'Number of current rows: ' + str(self.grid.GetNumberRows())
    print 'Size of myDataList: ', len(self.myDataList)

    current, new = (self.grid.GetNumberRows(), len(self.myDataList))

    if new < current:
        #- Delete rows:
        self.grid.DeleteRows(0, current-new, True)

    if new > current:
        #- append rows:
        self.grid.AppendRows(new-current)


    #- Populate the grid with new data:
    print 'Num of rows has been modified to:', self.grid.GetSize()
    for i in range(len(self.myDataList)):
        self.grid.SetCellValue(i, 0, self.myDataList[i]['Name'])
        self.grid.SetCellValue(i, 1, self.myDataList[i]['Tag'])
        self.grid.SetCellValue(i, 2, self.myDataList[i]['ID'])
grayaii
  • 2,241
  • 7
  • 31
  • 47