I’ve found this tutorial Change wxGrid CheckBox with one click .
I’ve written similar code:
import wx, wx.grid
class MyGrid(wx.grid.Grid):
def init(self, *args, **kwargs):
wx.grid.Grid.init(self, *args, **kwargs)
self.CreateGrid(3,3)
self.RowLabelSize = 0
self.ColLabelSize = 20
attr = wx.grid.GridCellAttr()
attr.SetEditor(wx.grid.GridCellBoolEditor())
attr.SetRenderer(wx.grid.GridCellBoolRenderer())
self.SetColAttr(0,attr)
self.SetColSize(0, 20)
self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK,self.onMouse)
self.Bind(wx.grid.EVT_GRID_SELECT_CELL,self.onCellSelected)
self.Bind(wx.grid.EVT_GRID_EDITOR_CREATED, self.onEditorCreated)
def onMouse(self, event):
if event.Col == 0:
wx.CallLater(100,self.toggleCheckBox)
event.Skip()
def toggleCheckBox(self):
self.cb.Value = not self.cb.Value
self.afterCheckBox(self.cb.Value)
def onCellSelected(self, event):
if event.Col == 0:
wx.CallAfter(self.EnableCellEditControl)
event.Skip()
def onEditorCreated(self, event):
if event.Col == 0:
self.cb = event.Control
self.cb.WindowStyle |= wx.WANTS_CHARS
self.cb.Bind(wx.EVT_KEY_DOWN,self.onKeyDown)
self.cb.Bind(wx.EVT_CHECKBOX,self.onCheckBox)
event.Skip()
def onKeyDown(self, event):
if event.KeyCode == wx.WXK_UP:
if self.GridCursorRow > 0:
self.DisableCellEditControl()
self.MoveCursorUp(False)
elif event.KeyCode == wx.WXK_DOWN:
if self.GridCursorRow < (self.NumberRows-1):
self.DisableCellEditControl()
self.MoveCursorDown(False)
elif event.KeyCode == wx.WXK_LEFT:
if self.GridCursorCol > 0:
self.DisableCellEditControl()
self.MoveCursorLeft(False)
elif event.KeyCode == wx.WXK_RIGHT:
if self.GridCursorCol < (self.NumberCols-1):
self.DisableCellEditControl()
self.MoveCursorRight(False)
else:
event.Skip()
def onCheckBox(self, event):
self.afterCheckBox(event.IsChecked())
def afterCheckBox(self, isChecked):
print 'afterCheckBox',self.GridCursorRow,isChecked
class MyTable(wx.grid.PyGridTableBase):
def init(self, parent, data, colnames):
wx.grid.PyGridTableBase.init(self)
self.data = data
self.colnames = colnames
def GetNumberCols(self):
return len(self.colnames)
def GetNumberRows(self):
return len(self.data)
def GetValue(self, row, col):
if col == 0:
return True
d = self.data[row]
dd = d.get(self.colnames[col], None)
if dd:
return self.data[row][self.colnames[col]]
else:
return ''
def GetColLabelValue(self, col):
return self.colnames[col]
class TstDialog(wx.Dialog):
def init(self, prnt):
wx.Dialog.init(self, id=-1, parent=prnt, size=wx.Size(400, 300),
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
title=(‘Test’))
self.MainSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5)
self.MainSizer.AddGrowableRow(0)
self.MainSizer.AddGrowableCol(0)
self.MyGrid = MyGrid(parent=self)
colNames = [‘Checked’, ‘Name’, ‘Value’]
data = [{‘Checked’ : False, ‘Name’ : ‘var1’, ‘Value’ : ‘100’},
{‘Checked’ : True, ‘Name’ : ‘var2’, ‘Value’ : ‘300’}]
table = MyTable(parent=self, data=data, colnames=colNames)
self.MyGrid.SetTable(table, True)
self.MainSizer.Add(self.MyGrid, flag=wx.EXPAND)
self.ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
self.ApplyButton = wx.Button(self, label=‘Apply’)
self.ButtonSizer.Add(self.ApplyButton, border=5, flag=wx.ALL)
self.Bind(wx.EVT_BUTTON, self.OnApplyButton, self.ApplyButton)
self.MainSizer.Add(self.ButtonSizer)
self.SetSizer(self.MainSizer)
def OnApplyButton(self, event):
pass
if name == ‘main’:
app = wx.App(False)
dialog = TstDialog(None)
if dialog.ShowModal():
pass
dialog.Destroy()
app.MainLoop()
There is the following result and errors: line 1754, in SetValue
return controls.TextCtrl_SetValue(*args, **kwargs)
if i comment self.MyGrid.SetTable(table, True) then will be the follwoing result.
How i must implement GetValue(self, row, col) and SetValue(self, row, col) methods for MyTable class? I want there is in 1st column checkbox and in 2ns and 3th columns - text.