--- C:\Users\ntmccork\Downloads\wxPython-demo-4.0.1\demo\GridHugeTable.py	2020-04-10 02:54:57.000000000 -0700
+++ C:\Users\ntmccork\Downloads\wxPython-demo-4.0.1\demo\GridHugeTable_Error.py	2020-04-13 12:48:33.000000000 -0700
@@ -1,89 +1,169 @@
-#!/usr/bin/env python
-
 import wx
 import wx.grid as gridlib
 
-#---------------------------------------------------------------------------
 
 class HugeTable(gridlib.GridTableBase):
-
-    def __init__(self, log):
+    def __init__(self, log, parent):
         gridlib.GridTableBase.__init__(self)
+        self.parent = parent
         self.log = log
-
+        self.show_default_values = True
         self.odd=gridlib.GridCellAttr()
         self.odd.SetBackgroundColour("sky blue")
         self.even=gridlib.GridCellAttr()
         self.even.SetBackgroundColour("sea green")
+        self.filter_editors = []
+        self.filter_attrs = []
+        for i in range(self.GetNumberCols()):
+            fa = gridlib.GridCellAttr()
+            fa.SetBackgroundColour("sea green")
+            self.filter_attrs.append(fa)
+            fe = gridlib.GridCellChoiceEditor(['FILTER data', 'WHERE=', 'CONTAINS', '???'], True)
+            self.filter_editors.append(fe)
+            fa.SetEditor(fe)
 
     def GetAttr(self, row, col, kind):
-        attr = [self.even, self.odd][row % 2]
+        if row == 0:
+            print(f'GetAttr row 0 col {col} fe created {self.filter_editors[col].IsCreated()}')
+            attr = self.filter_attrs[col] #self.filter_editors[col][0]
+            if self.filter_editors[col].IsCreated():
+                self.filter_editors[col].IncRef()
+        else:
+            attr = [self.even, self.odd][row % 2]
         attr.IncRef()
         return attr
 
-
-
     # This is all it takes to make a custom data table to plug into a
     # wxGrid.  There are many more methods that can be overridden, but
     # the ones shown below are the required ones.  This table simply
     # provides strings containing the row and column values.
 
     def GetNumberRows(self):
         return 10000
 
     def GetNumberCols(self):
-        return 10000
+        return 5
 
     def IsEmptyCell(self, row, col):
         return False
 
     def GetValue(self, row, col):
-        return str( (row, col) )
+        if row == 0:
+            print(f'GetValue row {row} col {col}')
+            if self.filter_editors[col].IsCreated():
+                print(f'GetValue filter_editor IsCreated r {row} c {col}')
+                val = self.filter_editors[col].GetValue()
+            else:
+                val = 'FILTER data'
+            return val
+        if self.show_default_values:
+            return str((row, col))
+        return "Off"
 
     def SetValue(self, row, col, value):
-        self.log.write('SetValue(%d, %d, "%s") ignored.\n' % (row, col, value))
+        print('SetValue(%d, %d, "%s") ignored.\n' % (row, col, value))
 
+        if row==0 and self.filter_editors[col].IsCreated():
+            self.show_default_values = not self.show_default_values
+            self.parent.Refresh()
 
+
 #---------------------------------------------------------------------------
 
-
-
 class HugeTableGrid(gridlib.Grid):
     def __init__(self, parent, log):
         gridlib.Grid.__init__(self, parent, -1)
 
-        table = HugeTable(log)
+        table = HugeTable(log, parent)
+        self.table = table
+        self.parent = parent
 
         # The second parameter means that the grid is to take
         # ownership of the table and will destroy it when done.
         # Otherwise you would need to keep a reference to it, but that
         # would allow other grids to use the same table.
         self.SetTable(table, True)
 
         self.Bind(gridlib.EVT_GRID_CELL_RIGHT_CLICK, self.OnRightDown)
+        self.Bind(gridlib.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown)
+        self.Bind(gridlib.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden)
+        self.Bind(gridlib.EVT_GRID_EDITOR_CREATED, self.OnEditorCreated)
 
+    def OnEditorShown(self, evt):
+        # if evt.GetRow() == 0 and evt.GetCol() == 0 and \
+        #         wx.MessageBox("Are you sure you wish to edit this cell?",
+        #                       "Checking", wx.YES_NO) == wx.NO:
+        #     evt.Veto()
+        #     return
+        print("OnEditorShown: (%d,%d) %s\n" % (evt.GetRow(), evt.GetCol(),
+                                         evt.GetPosition()))
+        evt.Skip()
+
+    def OnEditorHidden(self, evt):
+        # if evt.GetRow() == 0 and evt.GetCol() == 0 and \
+        #         wx.MessageBox("Are you sure you wish to  finish editing this cell?",
+        #                       "Checking", wx.YES_NO) == wx.NO:
+        #     evt.Veto()
+        #     return
+        print("OnEditorHidden: (%d,%d) %s\n" % (evt.GetRow(),
+                                                evt.GetCol(),
+                                                evt.GetPosition()))
+        evt.Skip()
+
+    def OnEditorCreated(self, evt):
+        print("OnEditorCreated: (%d, %d) %s\n" % (evt.GetRow(),
+                                                  evt.GetCol(),
+                                                  evt.GetControl()))
+
     def OnRightDown(self, event):
-        print("hello")
+        print("OnRightDown")
         print(self.GetSelectedRows())
 
-
+    def OnClose(self, event):
+        print('OnClose')
+        self.Hide()
+        for i, fa in enumerate(self.table.filter_attrs):
+            fe = self.table.filter_editors[i]
+            if fe.IsCreated():
+                if fe.Control:
+                    print('hiding filter_editor control')
+                    fe.Control.Hide()
+            print(f'OnClose FilterAttr   refcount    {fa.RefCount}  col {i}')
+            print(f'OnClose FilterEditor refcount    {fe.RefCount}  col {i}')
+            while fa.RefCount > 1:
+                fa.DecRef()
+                print(f'OnClose DecRef FilterAttr   col {i}')
+            while fe.RefCount > 1:
+                fe.DecRef()
+                print(f'OnClose DecRef FilterEditor col {i}')
+        while self.table.odd.RefCount>1:
+            self.table.odd.DecRef()
+            print('DecRef odd')
+
+        while self.table.even.RefCount>1:
+            self.table.even.DecRef()
+            print('DecRef even')
+        print('OnClose END')
+        #event.Skip()
+        self.parent.Destroy()
+
+
 #---------------------------------------------------------------------------
 
 class TestFrame(wx.Frame):
     def __init__(self, parent, log):
         wx.Frame.__init__(self, parent, -1, "Huge (virtual) Table Demo", size=(640,480))
         grid = HugeTableGrid(self, log)
 
         grid.SetReadOnly(5,5, True)
+        self.Bind(wx.EVT_CLOSE, grid.OnClose)
 
+
 #---------------------------------------------------------------------------
 
 if __name__ == '__main__':
     import sys
     app = wx.App()
     frame = TestFrame(None, sys.stdout)
     frame.Show(True)
     app.MainLoop()
-
-
-#---------------------------------------------------------------------------
