sample app that returns values from grid?

Ooooh, that would help me out too!

Chris

Most of the examples I've seen for grids (e.g. the ones in Chapter 5
of Robin Dunn's book) only display data in a grid. I want to allow
editing and then retrieve the edited data back when I close the grid
window. Does anyone have a small sample illustrating how to do
this?

ok, I've cobbled together a sample app that does what I want. There's an initial small window that opens up (this would be your main app window). You can check the contents of the initial database with the 'Data' button. Then you can open the grid with the 'Grid' button and edit one or more of the data-fields; if you run from a console you'll see some print-out that confirms your new data. When you press the Save-Close button in the grid, the new data gets written to the database and the grid window is closed. (instead of a Save button, you could probably just wire up an OnClose method to the EVT_CLOSE event of the grid window). Back in the main app window, if you again use the 'Data' button, you'll see the newly edited contents of the database.

The problem for me was that in both my TestFrame and DataFrame I was using self.dm = DataManager(), which gave me two separate instances of DataManager that didn't talk to each other. I needed to define a single application-level instance, dm, which would be above and outside any of the classes, so that in each class I could then reference that with self.dm = dm. I'm sure this could be improved on by someone with more Python or wxPython experience, and I welcome any suggestions. Here's the sample app (base code courtesy of Robin Dunn in Chapter 5 of 'wxPython in Action'):

#gridGenericGetData.py

import wx
import wx.grid
import generictable
import pprint

data = (("Bob", "Dernier"), ("Ryne", "Sandberg"), ("Gary", "Matthews"),
        ("Leon", "Durham"), ("Keith", "Moreland"), ("Ron", "Cey"),
        ("Jody", "Davis"), ("Larry", "Bowa"), ("Rick", "Sutcliffe"))

colLabels = ("Last", "First")
rowLabels = ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")

class DataManager:
    def __init__(self):
        self.data = data
        self.olddata = None

    def SetNewData(self,newdata):
        self.olddata = self.data
        self.data = newdata

    def GetNewData(self):
        return self.data

#an instance to use app-wide, in all classes
dm = DataManager()

class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent, mydata):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = generictable.GenericTable(data, rowLabels,
                colLabels)
        self.tableBase = tableBase
        self.SetTable(tableBase)

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "A Grid", size=(275, 275))
        self.dm = dm
        grid = SimpleGrid(self,self.dm.GetNewData)
        self.grid = grid
        sizer = wx.BoxSizer(wx.VERTICAL)
        grid.SetSize((500,len(self.dm.GetNewData())*20))
        sizer.Add(grid, 0, flag=wx.EXPAND)
        panel = wx.Panel(self, -1)
        panel.SetSize((500,10))
        sizer.Add(panel, 0)
        panel = wx.Panel(self, -1)
        self.addButtonBar(panel, 0)
        sizer.Add(panel, 0)
        sizer.Fit(panel)
        #sizer2.SetMinSize((410,50))
        self.SetSizer(sizer)
        self.Fit()
        self.Bind(wx.EVT_CLOSE, self.OnbSaveClick)

    def buttonData(self):
        """define the buttons to be used in this widget"""
        return (("Save-Close",self.OnbSaveClick),("Cancel",self.OnbCloseClick))

    def addButtonBar(self,panel, yPos=0):
        """add a bunch of buttons"""
        xPos = 0
        for eachLabel, eachHandler in self.buttonData():
            pos = (xPos, yPos)
            button = self.addButton(panel,eachLabel,eachHandler,pos)
            xPos += button.GetSize().width

    def addButton(self,parent,label,handler,pos=(0,0)):
        """add a button to the button bar"""
        button = wx.Button(parent, -1, label, pos)
        self.Bind(wx.EVT_BUTTON, handler, button)
        if label == 'Save-Close': self.bSave = button
        if label == 'Cancel': self.bClose = button
        return button

    def OnbSaveClick(self,event):
        self.bSave.SetBackgroundColour('LightBlue')
        self.bSave.Refresh()
        #debug: wx.MessageBox("I will save your changes","Save", wx.OK)
        newdata = self.grid.tableBase.ReturnValue()
        print "grid has returned this data:\n", pprint.pprint(newdata)
        self.dm.SetNewData(newdata)
        print "new stored data is:\n", pprint.pprint(self.dm.GetNewData())
        self.Destroy()

    def OnbCloseClick(self,event):
        self.bClose.SetBackgroundColour('LightBlue')
        self.bClose.Refresh()
        self.Destroy()

    def OnCloseWindow(self,event):
        wx.MessageBox("Please use the Close button to close this window", "Close", wx.OK | wx.ICON_WARNING)
        event.Skip()

    def ReturnValue(self):
        newdata = self.grid.ReturnValue()
        print newdata

class DataFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self,parent, -1, "Data app")
        self.frame = None
        self.dm = dm
        panel = wx.Panel(self, -1)
        label = wx.StaticText(panel, -1, "1. Press 'Data' button to see initial data\n"
                              "2. Press 'Grid' to generate grid, edit some data\n"
                              "3. Press 'Data' again to see the changed data.")
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(panel, 0, wx.ALL, 5)
        h = label.GetSize().height+5
        self.addButtonBar(self, h)
        self.SetSizer(self.sizer)
        self.Fit()

    def buttonData(self):
        """define the buttons to be used in this widget"""
        return (("Data",self.OnbDataClick),("Grid",self.OnbGridClick),("Close",self.OnbCloseClick))

    def addButtonBar(self,parent, yPos=0):
        """add a bunch of buttons"""
        btns = wx.StdDialogButtonSizer()
        xPos = 0
        for eachLabel, eachHandler in self.buttonData():
            pos = (xPos, yPos)
            button = self.addButton(parent,eachLabel,eachHandler,pos)
            btns.AddButton(button)
            xPos += button.GetSize().width
        self.SetSize((xPos,button.GetSize().height+5))
        btns.Realize()
        self.sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)

    def addButton(self,parent,label,handler,pos=(0,0)):
        """add a button to the button bar"""
        button = wx.Button(parent, -1, label, pos)
        self.Bind(wx.EVT_BUTTON, handler, button)
        if label == 'Grid': self.bGrid = button
        if label == 'Data': self.bData = button
        if label == 'Close': self.bClose = button
        return button

    def OnbGridClick(self,event):
        self.bGrid.SetBackgroundColour('LightBlue')
        self.bGrid.Refresh()
        frame = TestFrame(None)
        self.frame = frame
        frame.Show(True)
        event.Skip()

    def OnbDataClick(self,event):
        self.bData.SetBackgroundColour('LightBlue')
        self.bData.Refresh()
        displaydata = self.dm.GetNewData()
        dataList = ["%s %s" % (x[0],x[1]) for x in displaydata]
        wx.MessageBox("\n".join(dataList), "Data", wx.OK)

    def OnbCloseClick(self,event):
        self.bClose.SetBackgroundColour('LightBlue')
        self.bClose.Refresh()
        self.Destroy()

if __name__ == '__main__':
    app = wx.PySimpleApp()
    appframe = DataFrame(None)
    appframe.Show(True)

    app.MainLoop()

ยทยทยท

----- Original Message ----
From: Christopher Anderson <sidewinder.asu@gmail.com>
To: wxPython-users@lists.wxwidgets.org
Sent: Sunday, December 10, 2006 11:06:53 AM
Subject: Re: [wxPython-users] sample app that returns values from grid?

On 12/8/06, Stewart Midwinter <midtoad@yahoo.com> wrote:

------------------------------------

#generictable.py

import wx
import wx.grid
import pprint

class GenericTable(wx.grid.PyGridTableBase):

    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = [list(x) for x in data]
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        try :
            self.data[row][col] = value
        except IndexError :
            self.data.append([''] * self.GetNumberCols())
            msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
            self.GetView().ProcessTableMessage(msg)
            self.data[row][col] = value
        print "I'm at row %s, col %s with value %s and data:\n%s" % (row, col, value, self.data)

    def ReturnValue(self):
        print "I'm returning this data:\n", pprint.pprint(self.data)
        return self.data

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around