3 import  wx
.grid 
as gridlib
 
   5 #--------------------------------------------------------------------------- 
   7 class CustomDataTable(gridlib
.PyGridTableBase
): 
   8     def __init__(self
, log
): 
   9         gridlib
.PyGridTableBase
.__init
__(self
) 
  12         self
.colLabels 
= ['ID', 'Description', 'Severity', 'Priority', 'Platform', 
  13                           'Opened?', 'Fixed?', 'Tested?', 'TestFloat'] 
  15         self
.dataTypes 
= [gridlib
.GRID_VALUE_NUMBER
, 
  16                           gridlib
.GRID_VALUE_STRING
, 
  17                           gridlib
.GRID_VALUE_CHOICE 
+ ':only in a million years!,wish list,minor,normal,major,critical', 
  18                           gridlib
.GRID_VALUE_NUMBER 
+ ':1,5', 
  19                           gridlib
.GRID_VALUE_CHOICE 
+ ':all,MSW,GTK,other', 
  20                           gridlib
.GRID_VALUE_BOOL
, 
  21                           gridlib
.GRID_VALUE_BOOL
, 
  22                           gridlib
.GRID_VALUE_BOOL
, 
  23                           gridlib
.GRID_VALUE_FLOAT 
+ ':6,2', 
  27             [1010, "The foo doesn't bar", "major", 1, 'MSW', 1, 1, 1, 1.12], 
  28             [1011, "I've got a wicket in my wocket", "wish list", 2, 'other', 0, 0, 0, 1.50], 
  29             [1012, "Rectangle() returns a triangle", "critical", 5, 'all', 0, 0, 0, 1.56] 
  34     #-------------------------------------------------- 
  35     # required methods for the wxPyGridTableBase interface 
  37     def GetNumberRows(self
): 
  38         return len(self
.data
) + 1 
  40     def GetNumberCols(self
): 
  41         return len(self
.data
[0]) 
  43     def IsEmptyCell(self
, row
, col
): 
  45             return not self
.data
[row
][col
] 
  49     # Get/Set values in the table.  The Python version of these 
  50     # methods can handle any data-type, (as long as the Editor and 
  51     # Renderer understands the type too,) not just strings as in the 
  53     def GetValue(self
, row
, col
): 
  55             return self
.data
[row
][col
] 
  59     def SetValue(self
, row
, col
, value
): 
  61             self
.data
[row
][col
] = value
 
  64             self
.data
.append([''] * self
.GetNumberCols()) 
  65             self
.SetValue(row
, col
, value
) 
  67             # tell the grid we've added a row 
  68             msg 
= gridlib
.GridTableMessage(self
,            # The table 
  69                     gridlib
.GRIDTABLE_NOTIFY_ROWS_APPENDED
, # what we did to it 
  73             self
.GetView().ProcessTableMessage(msg
) 
  76     #-------------------------------------------------- 
  77     # Some optional methods 
  79     # Called when the grid needs to display labels 
  80     def GetColLabelValue(self
, col
): 
  81         return self
.colLabels
[col
] 
  83     # Called to determine the kind of editor/renderer to use by 
  84     # default, doesn't necessarily have to be the same type used 
  85     # natively by the editor/renderer if they know how to convert. 
  86     def GetTypeName(self
, row
, col
): 
  87         return self
.dataTypes
[col
] 
  89     # Called to determine how the data can be fetched and stored by the 
  90     # editor and renderer.  This allows you to enforce some type-safety 
  92     def CanGetValueAs(self
, row
, col
, typeName
): 
  93         colType 
= self
.dataTypes
[col
].split(':')[0] 
  94         if typeName 
== colType
: 
  99     def CanSetValueAs(self
, row
, col
, typeName
): 
 100         return self
.CanGetValueAs(row
, col
, typeName
) 
 106 #--------------------------------------------------------------------------- 
 110 class CustTableGrid(gridlib
.Grid
): 
 111     def __init__(self
, parent
, log
): 
 112         gridlib
.Grid
.__init
__(self
, parent
, -1) 
 114         table 
= CustomDataTable(log
) 
 116         # The second parameter means that the grid is to take ownership of the 
 117         # table and will destroy it when done.  Otherwise you would need to keep 
 118         # a reference to it and call it's Destroy method later. 
 119         self
.SetTable(table
, True) 
 121         self
.SetRowLabelSize(0) 
 123         self
.AutoSizeColumns(False) 
 125         gridlib
.EVT_GRID_CELL_LEFT_DCLICK(self
, self
.OnLeftDClick
) 
 128     # I do this because I don't like the default behaviour of not starting the 
 129     # cell editor on double clicks, but only a second click. 
 130     def OnLeftDClick(self
, evt
): 
 131         if self
.CanEnableCellControl(): 
 132             self
.EnableCellEditControl() 
 135 #--------------------------------------------------------------------------- 
 137 class TestFrame(wx
.Frame
): 
 138     def __init__(self
, parent
, log
): 
 141             self
, parent
, -1, "Custom Table, data driven Grid  Demo", size
=(640,480) 
 144         p 
= wx
.Panel(self
, -1, style
=0) 
 145         grid 
= CustTableGrid(p
, log
) 
 146         b 
= wx
.Button(p
, -1, "Another Control...") 
 148         self
.Bind(wx
.EVT_BUTTON
, self
.OnButton
, b
) 
 149         b
.Bind(wx
.EVT_SET_FOCUS
, self
.OnButtonFocus
) 
 150         bs 
= wx
.BoxSizer(wx
.VERTICAL
) 
 151         bs
.Add(grid
, 1, wx
.GROW|wx
.ALL
, 5) 
 155     def OnButton(self
, evt
): 
 156         print "button selected" 
 158     def OnButtonFocus(self
, evt
): 
 162 #--------------------------------------------------------------------------- 
 164 if __name__ 
== '__main__': 
 166     app 
= wx
.PySimpleApp() 
 167     frame 
= TestFrame(None, sys
.stdout
) 
 172 #---------------------------------------------------------------------------