wxPython - wxGrid - How to detect which column mov

2019-07-23 18:29发布

问题:

When the user drags a column to a new index, the wx.grid.EVT_GRID_COL_MOVE event is triggered. The handler receives a wx.grid.GridEvent which contains the property Col which contains the old index of the moved column. The event doesn't appear to contain any attributes detailing where the column has been moved to though. How do I figure that out?

回答1:

In case of theEVT_GRID_COL_MOVE event, GridEvent.GetCol() returns the ID of the column that is being moved. The actual position of the column can be obtained with Grid.GetColPos(colId). However, there's a difference between wxWidgets 2.8 and wx 2.9:

In wx 2.8, EVT_GRID_COL_MOVE is sent after the column has been moved which would prevent you from vetoing the event. Therefore calling GetColPos() during the event will return the new position of the column.

In wx 2.9, EVT_GRID_COL_MOVE is triggered before the column is moved and vetoing the event will prevent the column from being moved. Calling GetColPos() during the event will return the current position of the column.

The new position of the column is calculated internally, based on the mouse position. Duplicating that code in python may conflict with future releases which may break the program.

Using wx 2.9+ you can implement a workaround that will give you the new column position and allows you to 'veto' (or rather undo) the move:

self.Bind(wx.grid.EVT_GRID_COL_MOVE, self.OnColMove)
def OnColMove(self,evt):
    colId = evt.GetCol()
    colPos = self.grid.GetColPos(colId)
    wx.CallAfter(self.OnColMoved,colId,colPos)
    # allow the move to complete

def OnColMoved(self,colId,oldPos):
    # once the move is done, GetColPos() returns the new position
    newPos = self.grid.GetColPos(colId)
    print colId, 'from', oldPos, 'to', newPos
    undo = False
    if undo: # undo the move (as if the event was veto'd)
        self.grid.SetColPos(colId,oldPos)

Note that SetColPos will be called twice if the move has to be undone (once internally and a second time in OnColMoved).

Alternatively you could look into wx.lib.gridmovers.