📄 sheet.py
字号:
# sheet.py
# CSheet - A wxPython spreadsheet class.
# This is free software. Feel free to adapt it as you like.
# Author: Mark F. Russo (russomf@hotmail.com) 2002/01/31
#---------------------------------------------------------------------------
# 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o 2.5 compatability update.
# o Untested.
#
import string
import wx
import wx.grid
#---------------------------------------------------------------------------
class CTextCellEditor(wx.TextCtrl):
""" Custom text control for cell editing """
def __init__(self, parent, id, grid):
wx.TextCtrl.__init__(self, parent, id, "", style=wx.NO_BORDER)
self._grid = grid # Save grid reference
self.Bind(wx.EVT_CHAR, self.OnChar)
def OnChar(self, evt): # Hook OnChar for custom behavior
"""Customizes char events """
key = evt.GetKeyCode()
if key == wx.WXK_DOWN:
self._grid.DisableCellEditControl() # Commit the edit
self._grid.MoveCursorDown(False) # Change the current cell
elif key == wx.WXK_UP:
self._grid.DisableCellEditControl() # Commit the edit
self._grid.MoveCursorUp(False) # Change the current cell
elif key == wx.WXK_LEFT:
self._grid.DisableCellEditControl() # Commit the edit
self._grid.MoveCursorLeft(False) # Change the current cell
elif key == wx.WXK_RIGHT:
self._grid.DisableCellEditControl() # Commit the edit
self._grid.MoveCursorRight(False) # Change the current cell
evt.Skip() # Continue event
#---------------------------------------------------------------------------
class CCellEditor(wx.grid.PyGridCellEditor):
""" Custom cell editor """
def __init__(self, grid):
wx.grid.PyGridCellEditor.__init__(self)
self._grid = grid # Save a reference to the grid
def Create(self, parent, id, evtHandler):
""" Create the actual edit control. Must derive from wxControl.
Must Override
"""
self._tc = CTextCellEditor(parent, id, self._grid)
self._tc.SetInsertionPoint(0)
self.SetControl(self._tc)
if evtHandler:
self._tc.PushEventHandler(evtHandler)
def SetSize(self, rect):
""" Position/size the edit control within the cell rectangle. """
# Size text control to exactly overlay in-cell editing
self._tc.SetDimensions(rect.x+3, rect.y+3, rect.width-2, rect.height-2)
def Show(self, show, attr):
""" Show or hide the edit control. Use the attr (if not None)
to set colors or fonts for the control.
NOTE: There is no need to everride this if you don't need
to do something out of the ordinary.
"""
super(CCellEditor, self).Show(show, attr)
def PaintBackground(self, rect, attr):
""" Draws the part of the cell not occupied by the edit control. The
base class version just fills it with background colour from the
attribute.
NOTE: There is no need to everride this if you don't need
to do something out of the ordinary.
"""
# Call base class method.
super(CCellEditor, self).PaintBackground(self, rect, attr)
def BeginEdit(self, row, col, grid):
""" Fetch the value from the table and prepare edit control to begin editing.
Set the focus to the edit control. Must Override.
"""
self._startValue = grid.GetTable().GetValue(row, col)
self._tc.SetValue(self._startValue)
self._tc.SetFocus()
# Select the text when initiating an edit so that subsequent typing
# replaces the contents.
self._tc.SetSelection(0, self._tc.GetLastPosition())
def EndEdit(self, row, col, grid):
""" Commit editing the current cell. Returns True if the value has changed.
If necessary, the control may be destroyed. Must Override.
"""
changed = False # Assume value not changed
val = self._tc.GetValue() # Get value in edit control
if val != self._startValue: # Compare
changed = True # If different then changed is True
grid.GetTable().SetValue(row, col, val) # Update the table
self._startValue = '' # Clear the class' start value
self._tc.SetValue('') # Clear contents of the edit control
return changed
def Reset(self):
""" Reset the value in the control back to its starting value. Must Override. """
self._tc.SetValue(self._startValue)
self._tc.SetInsertionPointEnd()
def IsAcceptedKey(self, evt):
""" Return True to allow the given key to start editing. The base class
version only checks that the event has no modifiers. F2 is special
and will always start the editor.
"""
return (not (evt.ControlDown() or evt.AltDown())
and evt.GetKeyCode() != wx.WXK_SHIFT)
def StartingKey(self, evt):
""" If the editor is enabled by pressing keys on the grid, this will be
called to let the editor react to that first key.
"""
key = evt.GetKeyCode() # Get the key code
ch = None # Handle num pad keys
if key in [ wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3,
wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7,
wx.WXK_NUMPAD8, wx.WXK_NUMPAD9]:
ch = chr(ord('0') + key - wx.WXK_NUMPAD0)
elif key == wx.WXK_BACK: # Empty text control when init w/ back key
ch = ""
# Handle normal keys
elif key < 256 and key >= 0 and chr(key) in string.printable:
ch = chr(key)
if not evt.ShiftDown():
ch = ch.lower()
if ch is not None: # If are at this point with a key,
self._tc.SetValue(ch) # replace the contents of the text control.
self._tc.SetInsertionPointEnd() # Move to the end so that subsequent keys are appended
else:
evt.Skip()
def StartingClick(self):
""" If the editor is enabled by clicking on the cell, this method will be
called to allow the editor to simulate the click on the control.
"""
pass
def Destroy(self):
""" Final cleanup
NOTE: There is no need to everride this if you don't need
to do something out of the ordinary.
"""
super(CCellEditor, self).Destroy()
def Clone(self):
""" Create a new object which is the copy of this one. Must Override. """
return CCellEditor()
#---------------------------------------------------------------------------
class CSheet(wx.grid.Grid):
def __init__(self, parent):
wx.grid.Grid.__init__(self, parent, -1)
# Init variables
self._lastCol = -1 # Init last cell column clicked
self._lastRow = -1 # Init last cell row clicked
self._selected = None # Init range currently selected
# Map string datatype to default renderer/editor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -