#-*-coding:utf-8
#-------------------------------------------------------------------------------#Name: 模块1#Purpose:#
#Author: ankier#
#Created: 14/10/2012#Copyright: (c) ankier 2012#Licence: #-------------------------------------------------------------------------------
importwx, wx.grid as grd#grid column类型
classGridColumnControlKind:
Text="Text"CheckBox= "CheckBox"Colour= "Colour"
#定购的Grid cell color editor
classGridCellColorEditor(grd.PyGridCellEditor):defCreate(self, parent, id, evtHandler):"""Called to create the control, which must derive from wx.Control.
*Must Override*"""self.__Parent =parent
self.__ColorDialog =None
self.__ColorButton = wx.Button(parent, id, "")
self.SetControl(self.__ColorButton)#添加新的event handler, 防止 弹出窗口后, cell 自动editor
newEventHandler =wx._core.EvtHandler()ifevtHandler:
self.__ColorButton.PushEventHandler(newEventHandler)
self.__ColorButton.Bind(wx.EVT_BUTTON, self.OnClick)defOnClick(self, event):
self.__ColorButton.SetFocus()
self.ShowColorDialog()defSetSize(self, rect):"""Called to position/size the edit control within the cell rectangle.
If you don't fill the cell (the rect) then be sure to override
PaintBackground and do something meaningful there."""self.__ColorButton.SetDimensions(rect.x,rect.y,rect.width+2,rect.height+2,wx.SIZE_ALLOW_MINUS_ONE)defClone(self):"""Create a new object which is the copy of this one
*Must Override*"""
returnGridCellColorEditor()defBeginEdit(self, row, col, grid):"""Fetch the value from the table and prepare the edit control
to begin editing. Set the focus to the edit control.
*Must Override*"""self.startValue=grid.GetTable().GetValue(row, col)
self.endValue=self.startValue
self.__ColorButton.SetBackgroundColour(self.startValue)defEndEdit(self, row, col, grid):"""Complete the editing of the current cell. Returns True if the value
has changed. If necessary, the control may be destroyed.
*Must Override*"""changed=Falseif self.endValue !=self.startValue:
changed=True
grid.GetTable().SetValue(row, col, self.endValue)#update the table
self.startValue = ''
returnchangeddefShowColorDialog(self):
colorDialog= wx.ColourDialog(self.__Parent)
self.__ColorDialog =colorDialog
colorDialog.GetColourData().SetColour(self.startValue)if wx.ID_OK ==colorDialog.ShowModal():
data=colorDialog.GetColourData()
colour=data.GetColour()
self.__ColorButton.SetBackgroundColour(colour)
self.endValue=colourdel self.__ColorDialogself.__ColorDialog =None#定购颜色cell colour column
classGridCellColorRender(grd.PyGridCellRenderer):def __init__(self):
grd.PyGridCellRenderer.__init__(self)defDraw(self, grid, attr, dc, rect, row, col, isSelected):
color=grid.GetTable().GetValue(row, col)
dc.SetBrush(wx.Brush(color, wx.SOLID))
dc.SetPen(wx.TRANSPARENT_PEN)
dc.DrawRectangleRect(rect)
dc.SetBackgroundMode(wx.TRANSPARENT)defGetBestSize(self, grid, attr, dc, row, col):#text = grid.GetCellValue(row, col)#dc.SetFont(attr.GetFont())#w, h = dc.GetTextExtent(text)
return wx.Size(-1, -1)defClone(self):returnGridCellColorRender()#根据具体业务逻辑 定购grid的 table
classCustomGridTable(grd.PyGridTableBase):def __init__(self):
grd.PyGridTableBase.__init__(self)#添加Grid column head
self.colLabels = ["Name", "Visibility", "Min threshold", "Max threshold", "Colour"]#指定column对应的kind control
self.colControlKinds =[GridColumnControlKind.Text, GridColumnControlKind.CheckBox, GridColumnControlKind.Text, GridColumnControlKind.Text, GridColumnControlKind.Colour]
self.colControlEditorEnableStatus=[True, True, False, False, True]
self.rowLabels= ["","","","",""]#添加数据源
self.Data =[
['Mask 1', 1, "2.5","320.6",(200,20,100)]
,['Mask 2', 1, "2.5","320.6",(50,0,200)]
]defGetNumberRows(self):returnlen(self.Data)defGetNumberCols(self):returnlen(self.colLabels)defIsEmptyCell(self, row, col):returnFalsedefGetValue(self, row, col):returnself.Data[row][col]defSetValue(self, row, col, value):
self.Data[row][col]=valuedefGetColLabelValue(self, col):returnself.colLabels[col]defGetRowLabelValue(self, row):returnself.rowLabels[row]defInsertRow(self, index, row):if len(self.Data)
self.GetView().BeginBatch()
msg=grd.GridTableMessage(self,
grd.GRIDTABLE_NOTIFY_ROWS_INSERTED
,index
,1)
self.GetView().ProcessTableMessage(msg)#... same thing for columns ....
self.GetView().EndBatch()
msg=grd.GridTableMessage(self, grd.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
self.GetView().ProcessTableMessage(msg)defDeleteRow(self, row):
rowIndex=self.Data.index(row )if rowIndex <0:returnself.Data.remove(row)
self.GetView().BeginBatch()
msg=grd.GridTableMessage(self,grd.GRIDTABLE_NOTIFY_ROWS_DELETED,
rowIndex,
)
self.GetView().ProcessTableMessage(msg)#... same thing for columns ....
self.GetView().EndBatch()
msg=grd.GridTableMessage(self, grd.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
self.GetView().ProcessTableMessage(msg)defClear(self):
self.GetView().BeginBatch()
msg=grd.GridTableMessage(self,grd.GRIDTABLE_NOTIFY_ROWS_DELETED,
0,
self.GetNumberCols()-1)
self.GetView().ProcessTableMessage(msg)#... same thing for columns ....
self.GetView().EndBatch()
self.Data=[]
msg=grd.GridTableMessage(self, grd.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
self.GetView().ProcessTableMessage(msg)defAppendRow(self, row):
self.Data.append(row)
self.GetView().BeginBatch()
msg=grd.GridTableMessage(self,
grd.GRIDTABLE_NOTIFY_ROWS_APPENDED,
)
self.GetView().ProcessTableMessage(msg)#... same thing for columns ....
self.GetView().EndBatch()
msg=grd.GridTableMessage(self, grd.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
self.GetView().ProcessTableMessage(msg)#对grid的功能进行封装 以便能方便的处理
classCustomGrid(grd.Grid):def __init__(self, parent, id, rowLabelSize = 0, customGridTable =None):
grd.Grid.__init__(self, parent,id)
self.RowLabelSize=rowLabelSize
self.__CustomTableSource =customGridTable
self.SetTable(self.__CustomTableSource, True)
self.__InitStyle()#设置column 对应的 editor
self.__InitColumnsEditor()#self.Bind(grd.EVT_GRID_CELL_LEFT_CLICK,self.__OnMouse)
self.Bind(grd.EVT_GRID_SELECT_CELL, self.__OnCellSelected)
self.Bind(grd.EVT_GRID_EDITOR_CREATED, self.__OnEditorCreated)def __InitStyle(self):
self.SetSelectionBackground(wx.Color(237 , 145 , 33))def __InitColumnsEditor(self):
index= -1
for columnKind in self.__CustomTableSource.colControlKinds:
index+= 1
if columnKind ==GridColumnControlKind.CheckBox:
self.__InitCheckBoxColumnEditor(index)elif columnKind ==GridColumnControlKind.Colour:
self.__InitColorColumnEditor(index)def __InitCheckBoxColumnEditor(self, columnIndex):
attr=grd.GridCellAttr()
attr.SetEditor(grd.GridCellBoolEditor())
attr.SetRenderer(grd.GridCellBoolRenderer())
self.SetColAttr(columnIndex, attr)def __InitColorColumnEditor(self, columnIndex):
attr=grd.GridCellAttr()
attr.SetEditor(GridCellColorEditor())
attr.SetRenderer(GridCellColorRender())
self.SetColAttr(columnIndex, attr)def __OnCellSelected(self,evt):if self.__CustomTableSource.colControlEditorEnableStatus[evt.Col]:
wx.CallAfter(self.EnableCellEditControl)
evt.Skip()#设置改行为选中状态
self.SelectRow(evt.Row)def __OnEditorCreated(self, event):pass
defForceRefresh(self):
grd.Grid.ForceRefresh(self)#主窗口
classTestFrame(wx.Frame):def __init__(self):
wx.Frame.__init__(self, None,title="GridTable",size=(500,200))
sizer=wx.BoxSizer(wx.HORIZONTAL)
addButton= wx.Button(self, -1, "Add")
deleteButton= wx.Button(self, -1, "Delete")
clearButton= wx.Button(self, -1, "Clear")
sizer.Add(addButton, 0, wx.SHAPED)
sizer.Add(deleteButton, 0, wx.SHAPED)
sizer.Add(clearButton, 0, wx.SHAPED)
table=CustomGridTable()
grid= CustomGrid(self, id = -1, customGridTable =table)
self.__Grid =grid
mainSizer=wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(sizer)
mainSizer.Add(grid,1, wx.EXPAND)
self.SetSizerAndFit(mainSizer)
addButton.Bind(wx.EVT_BUTTON, self.OnAddClick)
deleteButton.Bind(wx.EVT_BUTTON, self.OnDeleteClick)
clearButton.Bind(wx.EVT_BUTTON, self.OnClearClick)defOnClearClick(self, event):
table= self.__Grid.GetTable()
table.Clear()print self.__Grid.GetTable().DatadefOnDeleteClick(self, event):
table= self.__Grid.GetTable()
firstRow= table.Data[1]
table.DeleteRow(firstRow)print self.__Grid.GetTable().DatadefOnAddClick(self, event):
table= self.__Grid.GetTable()
table.InsertRow(1, ['insert index', 1, "2.5","110.6",(50,200,30)])print self.__Grid.GetTable().Datadefmain():
app=wx.PySimpleApp()
frame=TestFrame()
frame.Show()
app.MainLoop()if __name__ == '__main__':
main()