Re: Error closing dialog after editing grid
Andrea Gavana <[email protected]>
| Newsgroups | gmane.comp.python.wxpython |
|---|---|
| Message-ID | <CAEf70byZyee1SERkojgyU6Y9SnH5MifPAfszUUZNz=qHfEEanA@mail.gmail.com> |
Hi, On Wed, 6 Nov 2019 at 07:42, ioprst <[email protected]> wrote: > 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) > > 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() > > In self.table.ResetView, the StateTable.ResetView method is called > > 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) > > If I edit any cell and close the dialog, an error occurs > > 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/627 > > 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? > Where does customtreectrl enter this piece of code? > -- > You received this message because you are subscribed to the Google Groups > "wxPython-users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/wxpython-users/5e520854-f0c7-453f-b27f-48b63f75244a%40googlegroups.com > <https://groups.google.com/d/msgid/wxpython-users/5e520854-f0c7-453f-b27f-48b63f75244a%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "wxPython-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/wxpython-users/CAEf70byZyee1SERkojgyU6Y9SnH5MifPAfszUUZNz%3DqHfEEanA%40mail.gmail.com.