Search code examples
wxpython

Custom GridCellEditor crash python


I'm trying to set up a custom GridCellEditor My config is Windows 7-64 bits, Python3.4.3-32bits, wxPython-Phoenix 3.0.3

I took and adapted sample code from the book wxpython in action.

The CellEditor works fine, but when I try to validate the content (with TAB, or click somewhere else on the grid), Python crashes...

Some other code borrowed from Internet creates the same crash (eg here)

Can somebody help me on this ?


import wx
import wx.grid
import string

class UpCaseCellEditor(wx.grid.GridCellEditor):
    def __init__(self):
        wx.grid.GridCellEditor.__init__(self)

    def Create(self, parent, id, evtHandler):
        self._tc = wx.TextCtrl(parent, id, "")
        self._tc.SetInsertionPoint(0)
        self.SetControl(self._tc)

        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

        self._tc.Bind(wx.EVT_CHAR, self.OnChar)

    def SetSize(self, rect):
        self._tc.SetSize(rect.x, rect.y, rect.width+2, rect.height+2)

    def BeginEdit(self, row, col, grid):
        self.startValue = grid.GetTable().GetValue(row, col)
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()
        self._tc.SetFocus()
        self._tc.SetSelection(0, self._tc.GetLastPosition())

    def EndEdit(self, row, col, grid):
        changed = False
        val = self._tc.GetValue()
        if val != self.startValue:
            changed = True
            grid.GetTable().SetValue(row, col, val)
        self.startValue = ''
        self._tc.SetValue('')
        return changed

    def Reset(self):
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()

    def Clone(self):
        return UpCaseCellEditor()

    def StartingKey(self, evt):
        self.OnChar(evt)
        if evt.GetSkipped():
            self._tc.EmulateKeyPress(evt)

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key > 255:
            evt.Skip()
            return
        char = chr(key)
        if char in string.ascii_letters:
            char = char.upper()
            self._tc.WriteText(char)
        else:
            evt.Skip()


class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Grid Editor",
                             size=(640,480))
        grid = wx.grid.Grid(self)
        grid.CreateGrid(50,50)
        grid.SetCellEditor(0, 0, UpCaseCellEditor())

app = wx.App()
frame = TestFrame()
frame.Show()
app.MainLoop()      

I've tried with PyGridCellEditor (which is said to be deprecated ?)


>>> import wx
>>> wx.grid.PyGridCellEditor
class 'wx.core.deprecated.locals.DeprecatedClassProxy'

Btw, I get the same problem with PyGridCellEditor. As python crashes, I don't get any traceback from idle. The only information I have is from Windows:

Signature du problème :
  Nom d’événement de problème:  APPCRASH
  Nom de l’application: pythonw.exe
  Version de l’application: 0.0.0.0
  Horodatage de l’application:  54ecf082
  Nom du module par défaut: _core.pyd
  Version du module par défaut: 0.0.0.0
  Horodateur du module par défaut:  55cb1a46
  Code de l’exception:  c0000005
  Décalage de l’exception:  00012fa5
  Version du système:   6.1.7601.2.1.0.256.48
  Identificateur de paramètres régionaux:   2060
  Information supplémentaire n° 1:  0a9e
  Information supplémentaire n° 2:  0a9e372d3b4ad19135b953a78882e789
  Information supplémentaire n° 3:  0a9e
  Information supplémentaire n° 4:  0a9e372d3b4ad19135b953a78882e789
If there is something I can do to have more informations, juste tell me :)


Solution

  • Well, I finally found the solution: EndEdit actually takes one more positional argument oldval So, replacing

    def EndEdit(self, row, col, grid):
    
    with
    def EndEdit(self, row, col, grid, oldval):
    
    do the trick. The code could also be improved with this argument, I think. Beside, ApplyEdit(self, row, col, grid) should be overridden, and this is where the actual change to the table should be made...