Nov-06-2019, 07:25 AM
There is a dialogue on which there is a panel on which there is a grid.
Each grid column is assigned its own editor (in a class derived from GridTableBase)
In self.table.ResetView, the StateTable.ResetView method is called
If I edit any cell and close the dialog, an error occurs
I did everything as suggested in the solution, but this does not solve the problem.
The problem is solved only if in the OnGridCellChange method at the end call self.table._updateColAttrs (self.grid).
Why?
Each grid column is assigned its own editor (in a class derived from GridTableBase)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
class StatePanel(wx.Panel): def __init__( self , parent, states): super ().__init__(parent) topsizer = wx.FlexGridSizer(rows = 1 , cols = 2 , vgap = 10 , hgap = 10 ) self .grid = CustomGrid( self , size = ( - 1 , 100 )) self .grid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self .OnGridCellChange) topsizer.Add( self .grid, proportion = 1 , flag = wx.EXPAND) self .SetSizer(topsizer) defaultValue = _StateInfos( 0 , '0' , 'Состояние 0' , YELLOW) self .states = states if not self .states: self .states.append(defaultValue.copy()) self .table = StateTable( self .states, GetStateTableColnames()) self .RefreshStates() def RefreshStates( self ): data = [] for num, state in enumerate ( self .states): state.Number = num + 1 data.append(state) self .table.SetData(data) self .table.ResetView( self .grid) def OnGridCellChange( self , event): row, col = event.GetRow(), event.GetCol() colname = self .table.GetColLabelValue(col, False ) value = self .table.GetValue(row, col) message = None if colname = = 'Code' : if not value: message = 'Значение кода не может быть пустым.' else : for r in range ( self .table.GetNumberRows()): if r ! = row: code = self .table.GetValueByName(r, 'Code' ) if value = = code: message = f 'Код {value} уже используется.' break if message is not None : wx.CallAfter(showErrorMessage, message) event.Veto() else : event.Skip() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
class StateTable(wx.grid.GridTableBase): ... def ResetView( self , grid): """ (wx.grid.Grid) -> Reset the grid view. Call this to update the grid if rows and columns have been added or deleted """ grid.CloseEditControl() grid.BeginBatch() for current, new, delmsg, addmsg in [ ( self ._rows, self .GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED ), ( self ._cols, self .GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED ) ]: if new < current: msg = wx.grid.GridTableMessage( self , delmsg, new, current - new) grid.ProcessTableMessage(msg) elif new > current: msg = wx.grid.GridTableMessage( self , addmsg, new - current) grid.ProcessTableMessage(msg) self .UpdateValues(grid) grid.EndBatch() self ._rows = self .GetNumberRows() self ._cols = self .GetNumberCols() # update the column rendering scheme self ._updateColAttrs(grid) # update the scrollbars and the displayed part of the grid grid.AdjustScrollbars() grid.ForceRefresh() def _updateColAttrs( self , grid): for row in range ( self .GetNumberRows()): for col in range ( self .GetNumberCols()): editor = None renderer = None colname = self .GetColLabelValue(col, False ) if col ! = 0 : grid.SetReadOnly(row, col, False ) if colname = = 'Code' : editor = wx.grid.GridCellNumberEditor() renderer = wx.grid.GridCellNumberRenderer() elif colname = = 'Text' : editor = wx.grid.GridCellTextEditor() renderer = wx.grid.GridCellStringRenderer() elif colname = = 'Text colour' : editor = GridCellColourEditor() renderer = GridCellColourRenderer() else : grid.SetReadOnly(row, col, True ) grid.SetCellEditor(row, col, editor) grid.SetCellRenderer(row, col, renderer) |
Error:wx._core.wxAssertionError: C++ assertion "GetEventHandler() == this" failed at ..\..\src\common\wincmn.cpp(478) in wxWindowBase::~wxWindowBase(): any pushed event handlers must have been removed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Python37-32\lib\site-packages\wx\lib\agw\customtreectrl.py", line 8183, in OnInternalIdle
if not self.HasAGWFlag(TR_MULTIPLE) and not self.GetSelection():
File "C:\Python37-32\lib\site-packages\wx\lib\agw\customtreectrl.py", line 3534, in HasAGWFlag
return bool(self._agwStyle & flag)
SystemError: <class 'bool'> returned a result with an error set
I saw the topic: https://github.com/wxWidgets/Phoenix/issues/627I did everything as suggested in the solution, but this does not solve the problem.
The problem is solved only if in the OnGridCellChange method at the end call self.table._updateColAttrs (self.grid).
Why?