不解的grid拖动列
appletian520
|
1#
appletian520 发表于 2008-09-28 10:41
不解的grid拖动列
DEMO里面用的是字典。换成pymssql生成数据后,测试只能移动列标,列里面的内容没有变化!
identifiers = ['id','ds','sv','pr','pl','op','fx','ts'] rowLabels = ['Row1','Row2','Row3'] colLabels = {'id':'ID','ds':'Description','sv':'Severity', 'pr':'Priority','pl':'Platform','op':'Opened?', 'fx':'Fixed?','ts':'Tested?'} data = [{'id':1010, 'ds':"The foo doesn't bar", 'sv':"major", 'pr':1, 'pl':'MSW', 'op':1, 'fx':1, 'ts':1 }, {'id':1011, 'ds':"I've got a wicket in my wocket", 'sv':"wish list", 'pr':2, 'pl':'other', 'op':0, 'fx':0, 'ts':0 }, {'id':1012, 'ds':"Rectangle() returns a triangle", 'sv':"critical", 'pr':5, 'pl':'all', 'op':0, 'fx':0, 'ts':0 } ] # -*- coding: cp936 -*- import wx import wx.grid import wx.lib.gridmovers as gridmovers import pymssql connect=pymssql.connect(host='wxpython',user='sa',password='',database='THIS4_0807') cursor=connect.cursor() ascordesc=True class LineupTable(wx.grid.PyGridTableBase): def __init__(self,data,fields): wx.grid.PyGridTableBase.__init__(self) self.data=data self.fields=fields ## self.dataTypes = [wx.grid.GRID_VALUE_STRING, ## wx.grid.GRID_VALUE_STRING, ## #gridlib.GRID_VALUE_CHOICE + 'nly in a million years!,wish list,minor,normal,major,critical', ## #gridlib.GRID_VALUE_NUMBER + ':1,5', ## #gridlib.GRID_VALUE_CHOICE + ':all,MSW,GTK,other', ## #gridlib.GRID_VALUE_BOOL, ## #gridlib.GRID_VALUE_BOOL, ## #gridlib.GRID_VALUE_BOOL, ## wx.grid.GRID_VALUE_FLOAT + ':6,2', ## ] #---Grid cell attributes self.odd = wx.grid.GridCellAttr() self.odd.SetBackgroundColour("grey" self.odd.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)) self.even = wx.grid.GridCellAttr() self.even.SetBackgroundColour("white" self.even.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD)) #---Mandatory constructors for grid def GetNumberRows(self): # if len(self.data)<10: # rowcounts=10 #else: #rowcounts=len(self.data) return len(self.data) def GetNumberCols(self): return len(self.fields) def GetColLabelValue(self, col): return self.fields[col] def IsEmptyCell(self, row, col): if self.data[row][col] == "" or self.data[row][col] is None: return True else: return False # def GetValue(self, row, col): # value = self.data[row][col] # if value is not None: # return value # else: # return '' # # def SetValue(self, row, col, value): # #print col # def innerSetValue(row, col, value): # try: # self.data[row][col] = value # except IndexError: # # add a new row # self.data.append([''] * self.GetNumberCols()) # innerSetValue(row, col, value) # # # tell the grid we've added a row # msg = gridlib.GridTableMessage(self, # The table # gridlib.GRIDTABLE_NOTIFY_ROWS_APPENDED, # what we did to it # 1 # how many # ) # # self.GetView().ProcessTableMessage(msg) # innerSetValue(row, col, value) def GetValue(self, row, col): #id = self.fields[col] return self.data[row][col] def SetValue(self, row, col, value): #id = self.fields[col] self.data[row][col] = value #-------------------------------------------------- # Some optional methods # Called when the grid needs to display column labels # def GetColLabelValue(self, col): # #id = self.fields[col] # return self.fields[col][0] def GetAttr(self, row, col, kind): attr = [self.even, self.odd][row % 2] attr.IncRef() return attr def SortColumn(self, col,ascordesc): """ col -> sort the data based on the column indexed by col """ name = self.fields[col] _data = [] for row in self.data: #print row #rowname, entry = row _data.append((row[col], row)) _data.sort(reverse=ascordesc) self.data = [] for sortvalue, row in _data: self.data.append(row) def AppendRow(self, row):#增加行 #print 'append' entry = [] for name in self.fields: entry.append('A') self.data.append(tuple(entry )) return True def MoveColumn(self,frm,to): grid = self.GetView() if grid: # Move the identifiers old = self.fields[frm] del self.fields[frm] if to > frm: self.fields.insert(to-1,old) else: self.fields.insert(to,old) print self.fields,frm,to # Notify the grid grid.BeginBatch() msg = wx.grid.GridTableMessage( self, wx.grid.GRIDTABLE_NOTIFY_COLS_INSERTED, to, 1 ) grid.ProcessTableMessage(msg) msg = wx.grid.GridTableMessage( self, wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, frm, 1 ) grid.ProcessTableMessage(msg) grid.EndBatch() grid.Refresh() # Move the row def MoveRow(self,frm,to): grid = self.GetView() if grid: # Move the rowLabels and data rows oldLabel = self.rowLabels[frm] oldData = self.data[frm] del self.rowLabels[frm] del self.data[frm] if to > frm: self.rowLabels.insert(to-1,oldLabel) self.data.insert(to-1,oldData) else: self.rowLabels.insert(to,oldLabel) self.data.insert(to,oldData) # Notify the grid grid.BeginBatch() msg = wx.grid.GridTableMessage( self, wx.grid.GRIDTABLE_NOTIFY_ROWS_INSERTED, to, 1 ) grid.ProcessTableMessage(msg) msg = wx.grid.GridTableMessage( self, wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, frm, 1 ) grid.ProcessTableMessage(msg) grid.EndBatch() class DragableGrid(wx.grid.Grid): def __init__(self, parent): wx.grid.Grid.__init__(self, parent ) cursor.execute('select top 2 blh,hzxm,qrrq from JK_YSQR_DK ') data = cursor.fetchall() fields = [cursor.description[0] for i in range(len(cursor.description))] table = LineupTable(data,fields) self.SetTable(table, True) #table = LineupTable() # The second parameter means that the grid is to take ownership of the # table and will destroy it when done. Otherwise you would need to keep # a reference to it and call it's Destroy method later. #self.SetTable(self.table, True) # Enable Column moving gridmovers.GridColMover(self) self.Bind(gridmovers.EVT_GRID_COL_MOVE, self.OnColMove, self) # Enable Row moving gridmovers.GridRowMover(self) self.Bind(gridmovers.EVT_GRID_ROW_MOVE, self.OnRowMove, self) # Event method called when a column move needs to take place def OnColMove(self,evt): frm = evt.GetMoveColumn() # Column being moved to = evt.GetBeforeColumn() # Before which column to insert self.GetTable().MoveColumn(frm,to) # Event method called when a row move needs to take place def OnRowMove(self,evt): frm = evt.GetMoveRow() # Row being moved to = evt.GetBeforeRow() # Before which row to insert self.GetTable().MoveRow(frm,to) class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, parent=None, id=-1, title='wx.grid.PyGridTableBase',size=(900,600)) #---Panel #panel = wx.Panel(self, -1) #---Buttons self.btn_1hr = wx.Button(self, -1, "RUN", pos=(10, 10),size=(100,40)) self.Bind(wx.EVT_BUTTON, self.OnClick, self.btn_1hr) self.btn_2hr = wx.Button(self, -1, "ADD", pos=(10, 35),size=(100,40)) self.Bind(wx.EVT_BUTTON, self.OnADD, self.btn_2hr) self.btn_3hr = wx.Button(self, -1, "DELETE", pos=(10, 60),size=(100,40)) self.btn_4hr = wx.Button(self, -1, "INSERT", pos=(10, 85),size=(100,40)) box = wx.BoxSizer(wx.VERTICAL) box.Add(self.btn_1hr, 1, wx.EXPAND,5) box.Add(self.btn_2hr, 1, wx.EXPAND,5) box.Add(self.btn_3hr, 1, wx.EXPAND,5) box.Add(self.btn_4hr, 1, wx.EXPAND,5) #---Grid self.grid =DragableGrid(self)#, pos=(140, 0), size=(900,400)) self.grid.SetRowLabelSize(40)#设置行标签的宽度 self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClick) #self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) box1 = wx.BoxSizer(wx.VERTICAL) box1.Add(self.grid, 1, wx.GROW|wx.ALL) cursor.execute('select top 2 blh,hzxm,qrrq from JK_YSQR_DK ') data = cursor.fetchall() fields = [cursor.description[0] for i in range(len(cursor.description))] self.table = LineupTable(data,fields) self.grid.SetTable(self.table, True) #---Grid properties self.grid.EnableEditing(True)#是否可以编辑 self.grid.SetDefaultCellAlignment(wx.ALIGN_LEFT, wx.ALIGN_RIGHT)#设置CELL的文本对齐方式 self.grid.SetSelectionBackground('red') self.grid.EnableDragColSize(enable=True)#控制列宽是否可以拉动 self.grid.EnableDragRowSize(enable=True)#控制行高是否可以拉动 self.grid.SetLabelBackgroundColour((100, 200, 150)) self.grid.SetLabelTextColour((255, 255, 255)) #---Column Sizes self.grid.AdjustScrollbars() self.grid.Refresh() Hbox = wx.BoxSizer(wx.HORIZONTAL) Hbox.Add(box, 0, wx.EXPAND) Hbox.Add(box1, 1, wx.EXPAND) #Vbox = wx.BoxSizer(wx.VERTICAL) #Vbox.Add(Hbox,0,wx.ALL|wx.EXPAND) self.SetSizer(Hbox) #self.Fit() #self.grid.AutoSize() #---Use below if want to size individual columns (index, size) #---Also have SetRowSize #grid.SetColSize(0, 150) def Reset(self): """reset the view based on the data in the table. Call this when rows are added or destroyed""" self.table.ResetView(self) def OnLabelRightClick(self, event): global ascordesc,row, col #self.SetStatusText('You Have Right-Clicked On Label "%s"!' % event.GetString()) row, col = event.GetRow(), event.GetCol() #print row, col self.table.SortColumn(col,ascordesc) if ascordesc: ascordesc=False else: ascordesc=True self.grid.Refresh() def OnADD(self,event): #self.table.AppendRow(row) #print (self.grid.SelectedRows) self.table.AppendRow(row) #self.grid.SetTable(self.table, True) self.grid.ForceRefresh() def OnClick(self, event): cursor.execute('select top 5 id as "编码",name as "名称" ,cast(memo as numeric(12,2)) as "单价" from YY_SFDXMK where memo>0') data1 = cursor.fetchall() fields1 = [cursor.description[0] for i in range(len(cursor.description))] self.table = LineupTable(data1,fields1) self.grid.SetTable(self.table, True) self.grid.EnableDragColSize(enable=True) self.grid.EnableDragRowSize(enable=True) #self.grid.AutoSize() self.grid.AdjustScrollbars() #self.grid.ForceRefresh() self.grid.Refresh() if __name__ == "__main__": app = wx.PySimpleApp() frame = MyFrame() frame.Show() app.MainLoop() |