The cell editor is a utility class for managing a wxControl instance for editing a particular data type. A particular instance of the editor (and thereby it's associated control) is used for all cells in the grid having the same data type.
Unfortunately, the editor is derived from an undocumented class, the wxGridCellWorker, whose methods I am inferring from usage within the wxPython demo.
The editor is shared among all cells having the same data type, this lets the system reuse the editing control for each cell, but requires that the editor have machinery in place for creating, moving, and setting the current value for that single control.
void Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler) -- Creates the actual edit control. Although it does not appear to be documented anywhere, after creating your control, call SetControl (I don't know what class provides SetControl, but it does appear to be available) and push the event handler for the control (I don't know why we do that, but I assume it has something to do with handling the default editing commands for the grid). For example:
def Create(self, parent, id, evtHandler): self.control = self.buttonClass( parent, id) self.SetControl(self.control) if evtHandler: self.control.PushEventHandler(evtHandler)
wxGridCellEditor* Clone() -- Create a new object which is the copy of this one. My implementations tend to look something like:
def Clone(self): return self.__class__()
bool IsCreated() -- Return a Boolean value describing whether the control has been created. Note: I have never actually defined this method, I'm assuming that calling SetControl on the editor is making the default implementation return a suitable value.
Configuration for a Cell
When a particular cell is to be edited, it is necessary to have the editor's control moved so that it appears to be contained within the rectangle defined by the cell. You define a handler for SetSize which performs this resizing.
void SetSize(const wxRect& rect) -- Size and position the edit control. Note: calling wxWindow::SetDimensions (a wxPython alias for SetSize) on your control is useful for implementing this method.
The Edit Cycle
After the control has been positioned, the grid calls Show, to show the control on-screen, then BeginEdit to allow the editor to transfer data from the grid (or the table) to the control and set the Focus to the control.
void Show(bool show, wxGridCellAttr* attr = NULL) -- Show or hide the edit control, use the specified attributes to set colours/fonts for it. Note: I have never overridden this, the default implementation seems to do a Show on the control passed to SetControl.
Show needs to be overwritten if you wish to display more than than one control. For example, with a text control and a button:
def Show(self, show, attr): self.textBox.Show(show) self.browseButton.Show(show)
void BeginEdit(int row, int col, wxGrid* grid) -- Fetch the value from the table and prepare the edit control to begin editing. Set the focus to the edit control. Note: depending on your wxPython version the grid instance passed to this function isn't likely a pointer to your Python grid object.
From there, the grid calls one of two methods for handling the event which triggered the editing cycle (StartingKey or StartingClick), allowing the control to respond to those events.
void StartingKey(wxKeyEvent& event) -- If the editor is enabled by pressing keys on the grid, this will be called to let the editor do something about that first key if desired.
void StartingClick() -- If the editor is enabled by clicking on the cell, this method will be called.
While the control is active, a number of methods may be called in response to user interactions.
void HandleReturn(wxKeyEvent& event) -- Some types of controls on some platforms may need some help with the Return key. XXX Not sure what triggers this, whether it is simply the return key being pressed at all, or whether some particular condition triggers it.
void Reset() -- Reset the value in the control back to its starting value. You can either get this value from your table again, or store the original value in the editor to implement the method.
bool EndEdit(int row, int col, wxGrid* grid) -- Called to tell the editor that the editing cycle has finished (due to some user interaction, such as clicking on another cell). You need to finalize the editing of the value in your control, and determine whether that value has changed from the original value (returning a Boolean value indicating whether the value has changed). Note: I'm not sure if it is required to transfer the updated value back to the table here, or whether the grid will take care of it if changed == true is returned. I haven't noticed any ill effects from updating the value in my implementations of this method.
I have never had cause to use this, the default Destroy seems to properly clean up a control which has had SetControl called on it.
void Destroy() -- Final cleanup.
If the control is smaller than the size of the cell, there will be a background area displayed in the remaining space. This method is called to clear that background area. Apparently the cell attribute object will provide information on appropriate colors.
void PaintBackground(const wxRect& rectCell, wxGridCellAttr* attr) -- Draws the part of the cell not occupied by the control: the base class version just fills it with background colour from the attribute.
Back to the wxGrid Manual