Search code examples
pythongridwxpythonwxgrid

wxpython Event order


I have a wxPython gui with a grid. When a user clicks on certain cells, a drop-down menu will pop up.

self.window.Bind(wx.grid.EVT_GRID_SELECT_CELL, lambda event: self.on_left_click(event, self.grid, choices), self.grid)

The method on_left_click pulls up the drop-down menu and works as expected. The problem is that I want the default behavior for wx.grid.EVT_GRID_SELECT_CELL to happen first, and then for my custom method to fire. Normally, when you click on a grid cell, that cell's border gets bold. With my binding, the my drop-down menu appears first, and only once the drop-down menu is dismissed does the cell border get selected. I tried calling self.grid.SetGridCursor(row, col), but that generates a wx.grid.EVT_GRID_SELECT_CELL event, which causes a recursion max out and obviously is no good. I also tried using event.Skip() in the on_left_click code, but it doesn't seem to have an effect.

Here is the awkward, objectionable behavior (I just clicked on row 0, col 2): grid looking all weird

Here is the desired behavior:grid looking more appropriate

I am happy to provide more of the code if needed. I would like to do one of the following. One, somehow force wxPython to fully process wx.grid.EVT_GRID_SELECT_CELL before moving on to my custom drop-down menu. Two, manually duplicate the effect of "highlighting" the selected cell in my own code.

Thanks in advance for any help.

edit:

Here's what I ended up doing.

In place of wx.grid.EVT_GRID_SELECT_CELL, I used wx.grid.EVT_GRID_CELL_LEFT_CLICK which is essentially the first event to be fired when a user clicks on a grid cell, so I could fully customize the behavior following that initial click. Then, I could use this:

    self.grid.SetGridCursor(row, col)

to outline the cell without creating the infinite recursion error, as well as implementing a bunch of other behavior that is now working more smoothly. I also needed to use self.grid.Refresh().


Solution

  • Create a separate method for showing drop down menu and call it with wx.CallAfter.

    def on_left_click(self, event, grid, choices):
        event.Skip()
        self.grid.Refresh()
        wx.CallAfter(self.showMenu, grid=grid, choices=choices)
    
    
    def showMenu(self, grid=None, choices=None):
        # Drop down menu code goes here