I created a grid using wxPython and I need to monitor the data inserted by the user into one of the cells in my grid. I need to have an event due to every key press in the keyboard (like EVT_KEY_DOWN) and I can't find a way to do that. Right now I need to use a grid for this purpose so the solution must be something that can be integrated into wx.grid.
I tried to use GridCellEditor but it only gives the first key. Is there a way to integrate TextCtrl into a grid's cell or something like that?
As far as I can tell, unless told differently, a grid is a collection of TextCtrl's, so the key is to bind wx.EVT_KEY_DOWN
to them.
Here is one way to do it:
Note: I have added a few different element types for demonstration purposes.
Hopefully this is all that you require.
import wx
import wx.grid as gridlib
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "A key detecting grid", size=(1000,300))
panel = wx.Panel(self, wx.ID_ANY)
self.grid = gridlib.Grid(panel)
self.grid.CreateGrid(10, 8)
self.grid.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress) #Required for initial key press
self.grid.Bind(gridlib.EVT_GRID_EDITOR_CREATED, self.onEditorCreated) # For subsequent key presses
# -- Additional bits only for demonstration of isolating Text fields
# Boolean field dislays as a CheckBox
crbool = wx.grid.GridCellBoolRenderer()
cebool = wx.grid.GridCellBoolEditor()
self.grid.SetCellRenderer(1, 1, crbool)
self.grid.SetCellEditor(1, 1, cebool)
# Choice field
cechoice = wx.grid.GridCellChoiceEditor(['Choice 1','Choice 2','Choice 3'], allowOthers=False)
self.grid.SetCellEditor(1, 2, cechoice)
#Load special fields
self.grid.SetCellValue(1, 1, '1')
self.grid.SetCellValue(1, 2, 'Choice 2')
self.grid.SetColSize(0,200)
self.grid.SetColSize(2,200)
# --
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.grid, 1, wx.EXPAND, 5)
panel.SetSizerAndFit(sizer)
self.Show()
def OnKeyPress(self, event):
uk = event.UnicodeKey
key = chr(event.UnicodeKey)
shift = event.shiftDown
if not shift:
key = key.lower()
print("Key", uk, key)
event.Skip()
def onEditorCreated(self,event):
#Set TextCtrl element to want all char/key events for all keys
self.cb = event.Control
if event.Control.ClassName == "wxTextCtrl":
self.cb.SetWindowStyle(wx.WANTS_CHARS) # BEWARE! - Returns Tab, Enter, Arrow keys etc
self.cb.Bind(wx.EVT_KEY_DOWN,self.OnKeyPress)
else:
print("Non text cell - bailing out")
event.Skip()
if __name__ == "__main__":
app = wx.App()
frame = MyForm()
app.MainLoop()