python wxpython wx.grid动态增加行_wxPython控件学习之wx.grid.Grid (包括对GridCellEditor和GridCelRender的扩展,以支持更多的gri...

万俟浩
2023-12-01

#-*-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()

 类似资料: