wx.Grid staying in the same cell after editing

Good morning

I have a grid where in certain scenarios, after user input, the cursor needs to remain in the cell. I was just using MoveCursorUp after the EVT_GRID_CELL_CHANGED event to return the cursor to the previous position. Nonetheless, this does not work for the first row.

I ended up doing this:

import wx
import wx.grid

class GridFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.initialize()
    def initialize(self):
        # Create a wxGrid object
        self.grid = wx.grid.Grid(self, size=(420,700))


        self.grid.CreateGrid(5, 5)
        self.Show()
        self.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.onCellChange)
    def onCellChange(self, event) -> bool:
        '''
        Detects the change on a cell 
        '''
        #hacky thing below
        wx.CallLater(10,self.grid.MoveCursorUp,False)
        

if __name__ == '__main__':

    app = wx.App(0)
    frame = GridFrame(None)
    app.MainLoop()

In this way, using CallLater, it works. But this feels like a complete hack and I guess that there must be a proper way to do this. I suspect there is another event that was cancelling the effect of MoveCursorUp and with CallLater, it is executed after this “mysterious” event. Does someone have any ideas?

Thanks for your help :smiley:

1 Like

Good morning, Anastacius

You can find the solution to what you want to do in ‘/demo/GridSimpe.py’.
CnP the code fragment from the demo and modify your code as follows:

import wx
import wx.grid

class GridFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.initialize()

    def initialize(self):
        # Create a wxGrid object
        self.grid = wx.grid.Grid(self, size=(420,700))

        self.grid.CreateGrid(5, 5)
        self.Show()
        self.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.onCellChange)
        
        self.moveTo = None
        self.Bind(wx.EVT_IDLE, self.OnIdle)

    def onCellChange(self, event) -> bool:
        '''
        Detects the change on a cell 
        '''
        #hacky thing below
        ## wx.CallLater(10,self.grid.MoveCursorUp,False)

        # Show how to stay in a cell that has bad data.  We can't just
        # call SetGridCursor here since we are nested inside one so it
        # won't have any effect.  Instead, set coordinates to move to in
        # idle time.
        value = self.grid.GetCellValue(event.GetRow(), event.GetCol())

        if value == 'no good':
            self.moveTo = event.GetRow(), event.GetCol()

    def OnIdle(self, evt):
        if self.moveTo:
            self.grid.SetGridCursor(*self.moveTo)
            self.moveTo = None
            
        evt.Skip()


if __name__ == '__main__':

    app = wx.App(0)
    frame = GridFrame(None)
    app.MainLoop()

If you type “no good” into a cell, the cursor won’t move.

:memo: Make sure that if you installed python in “C:\Python38”, the wx demo launcher will be “C:\Python38\Scripts\wxdemo.exe”. Once launched, the demo code will be expanded to “~\AppData\Local\wxPython\wxPython-demo-4.x.x\demo”.