More grid demos and some bugs fixed

Made (virtual method) callbacks into Python code more safe, and
removed the confusion if there was a matching method in the base
class.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7081 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2000-04-08 08:11:20 +00:00
parent 487d976143
commit 87b389965c
28 changed files with 947 additions and 411 deletions

View File

@@ -0,0 +1,155 @@
from wxPython.wx import *
from wxPython.grid import *
import string
#---------------------------------------------------------------------------
class CustomDataTable(wxPyGridTableBase):
"""
"""
def __init__(self, log):
wxPyGridTableBase.__init__(self)
self.log = log
self.colLabels = ['ID', 'Description', 'Severity', 'Priority', 'Platform',
'Opened?', 'Fixed?', 'Tested?']
self.dataTypes = [wxGRID_VALUE_NUMBER,
wxGRID_VALUE_STRING,
wxGRID_VALUE_CHOICE + ':only in a million years!,wish list,minor,normal,major,critical',
wxGRID_VALUE_NUMBER + ':1,5',
wxGRID_VALUE_CHOICE + ':all,MSW,GTK,other',
wxGRID_VALUE_BOOL,
wxGRID_VALUE_BOOL,
wxGRID_VALUE_BOOL]
self.data = [
[1010, "The foo doesn't bar", "major", 1, 'MSW', 1, 1, 1],
[1011, "I've got a wicket in my wocket", "wish list", 2, 'other', 0, 0, 0],
[1012, "Rectangle() returns a triangle", "critical", 5, 'all', 0, 0, 0]
]
#--------------------------------------------------
# required methods for the wxPyGridTableBase interface
def GetNumberRows(self):
return len(self.data) + 1
def GetNumberCols(self):
return len(self.data[0])
def IsEmptyCell(self, row, col):
return not self.data[row][col]
# Get/Set values in the table. The Python version of these
# methods can handle any data-type, (as long as the Editor and
# Renderer understands the type too,) not just strings as in the
# C++ version.
def GetValue(self, row, col):
try:
return self.data[row][col]
except IndexError:
return ''
def SetValue(self, row, col, value):
try:
self.data[row][col] = value
except IndexError:
# add a new row
self.data.append([''] * self.GetNumberCols())
self.SetValue(row, col, value)
# tell the grid we've added a row
msg = wxGridTableMessage(self, # The table
wxGRIDTABLE_NOTIFY_ROWS_APPENDED, # what we did to it
1) # how many
self.GetView().ProcessTableMessage(msg)
#--------------------------------------------------
# optional methods
# Called when the grid needs to display labels
def GetColLabelValue(self, col):
return self.colLabels[col]
# Called to determine the kind of editor/renderer to use by
# default, doesn't necessarily have to be the same type used
# nativly by the editor/renderer if they know how to convert.
def GetTypeName(self, row, col):
return self.dataTypes[col]
# Called to determine how the data can be fetched and stored by the
# editor and renderer. This allows you to enforce some type-safety
# in the grid.
def CanGetValueAs(self, row, col, typeName):
colType = string.split(self.dataTypes[col], ':')[0]
if typeName == colType:
return true
else:
return false
def CanSetValueAs(self, row, col, typeName):
return self.CanGetValueAs(row, col, typeName)
#---------------------------------------------------------------------------
class CustTableGrid(wxGrid):
def __init__(self, parent, log):
wxGrid.__init__(self, parent, -1)
table = CustomDataTable(log)
# 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(table, true)
self.SetRowLabelSize(0)
self.SetMargins(0,0)
self.AutoSizeColumns(false)
EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick)
# I do this because I don't like the default behaviour of not starting the
# cell editor on double clicks, but only a second click.
def OnLeftDClick(self, evt):
if self.CanEnableCellControl():
self.EnableCellEditControl()
#---------------------------------------------------------------------------
class TestFrame(wxFrame):
def __init__(self, parent, log):
wxFrame.__init__(self, parent, -1, "Custom Table, data driven Grid Demo", size=(640,480))
grid = CustTableGrid(self, log)
#---------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = wxPySimpleApp()
frame = TestFrame(None, sys.stdout)
frame.Show(true)
app.MainLoop()
#---------------------------------------------------------------------------

View File

@@ -0,0 +1,71 @@
from wxPython.wx import *
from wxPython.grid import *
#---------------------------------------------------------------------------
class HugeTable(wxPyGridTableBase):
"""
This is all it takes to make a custom data table to plug into a
wxGrid. There are many more methods that can be overridden, but
the ones shown below are the required ones. This table simply
provides strings containing the row and column values.
"""
def __init__(self, log):
wxPyGridTableBase.__init__(self)
self.log = log
def GetNumberRows(self):
return 10000
def GetNumberCols(self):
return 10000
def IsEmptyCell(self, row, col):
return false
def GetValue(self, row, col):
return str( (row, col) )
def SetValue(self, row, col, value):
self.log.write('SetValue(%d, %d, "%s") ignored.\n' % (row, col, value))
#---------------------------------------------------------------------------
class HugeTableGrid(wxGrid):
def __init__(self, parent, log):
wxGrid.__init__(self, parent, -1)
table = HugeTable(log)
# 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(table, true)
#---------------------------------------------------------------------------
class TestFrame(wxFrame):
def __init__(self, parent, log):
wxFrame.__init__(self, parent, -1, "Huge (virtual) Table Demo", size=(640,480))
grid = HugeTableGrid(self, log)
#---------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = wxPySimpleApp()
frame = TestFrame(None, sys.stdout)
frame.Show(true)
app.MainLoop()
#---------------------------------------------------------------------------

View File

@@ -8,7 +8,9 @@ class SimpleGrid(wxGrid):
wxGrid.__init__(self, parent, -1)
self.log = log
self.CreateGrid(16, 16)
self.CreateGrid(25, 25)
# simple cell formatting
self.SetColSize(3, 200)
self.SetRowSize(4, 45)
self.SetCellValue(0, 0, "First cell")
@@ -18,6 +20,16 @@ class SimpleGrid(wxGrid):
self.SetCellTextColour(1, 1, wxRED)
self.SetCellBackgroundColour(2, 2, wxCYAN)
# attribute objects let you keep a set of formatting values
# in one spot, and reuse them if needed
attr = wxGridCellAttr()
attr.SetTextColour(wxBLACK)
attr.SetBackgroundColour(wxRED)
attr.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD))
# you can set cell attributes for the whole row (or column)
self.SetRowAttr(5, attr)
# test all the events
EVT_GRID_CELL_LEFT_CLICK(self, self.OnCellLeftClick)

View File

@@ -0,0 +1,179 @@
from wxPython.wx import *
from wxPython.grid import *
import string, random
#---------------------------------------------------------------------------
class MyCustomRenderer(wxPyGridCellRenderer):
def __init__(self):
wxPyGridCellRenderer.__init__(self)
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
dc.SetBackgroundMode(wxSOLID)
dc.SetBrush(wxBrush(wxBLACK, wxSOLID))
dc.SetPen(wxTRANSPARENT_PEN)
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
dc.SetBackgroundMode(wxTRANSPARENT)
dc.SetFont(attr.GetFont())
text = grid.GetCellValue(row, col)
colors = [wxRED, wxWHITE, wxCYAN]
x = rect.x + 1
y = rect.y + 1
for ch in text:
dc.SetTextForeground(random.choice(colors))
dc.DrawText(ch, x, y)
w, h = dc.GetTextExtent(ch)
x = x + w
if x > rect.right - 5:
break
def GetBestSize(self, grid, attr, dc, row, col):
text = grid.GetCellValue(row, col)
dc.SetFont(attr.GetFont())
w, h = dc.GetTextExtent(text)
return wxSize(w, h)
def Clone(self):
return MyCustomRenderer
#---------------------------------------------------------------------------
rendererDemoData = [
('wxGridCellStringRenderer\n(the default)', 'this is a text value', wxGridCellStringRenderer, ()),
('wxGridCellNumberRenderer', '12345', wxGridCellNumberRenderer, ()),
('wxGridCellFloatRenderer', '1234.5678', wxGridCellFloatRenderer, (6,2)),
('wxGridCellBoolRenderer', '1', wxGridCellBoolRenderer, ()),
('MyCustomRenderer', 'This is my renderer', MyCustomRenderer, ()),
]
editorDemoData = [
('wxGridCellTextEditor\n(the default)', 'Here is some more text', wxGridCellTextEditor, ()),
('wxGridCellNumberEditor\nwith min,max', '101', wxGridCellNumberEditor, (5, 10005)),
('wxGridCellNumberEditor\nwithout bounds', '101', wxGridCellNumberEditor, ()),
('wxGridCellFloatEditor', '1234.5678', wxGridCellFloatEditor, ()),
('wxGridCellBoolEditor', '1', wxGridCellBoolEditor, ()),
('wxGridCellChoiceEditor', 'one', wxGridCellChoiceEditor, (['one', 'two', 'three', 'four',
'kick', 'Microsoft', 'out the',
'door'], false)),
]
comboDemoData = [
('wxGridCellNumberRenderer\nwxGridCellNumberEditor', '20792', wxGridCellNumberRenderer, wxGridCellNumberEditor),
('wxGridCellBoolRenderer\nwxGridCellBoolEditor', '1', wxGridCellBoolRenderer, wxGridCellBoolEditor),
]
class EditorsAndRenderersGrid(wxGrid):
def __init__(self, parent, log):
wxGrid.__init__(self, parent, -1)
self.log = log
self.CreateGrid(25, 8)
renCol = 1
edCol = 4
self.SetCellValue(0, renCol, '''\
Cell Renderers are used to draw
the contents of the cell when they
need to be refreshed. Different
types of Renderers can be plugged in
to different cells in the grid, it can
even be automatically determined based
on the type of data in the cell.
''')
self.SetCellValue(0, edCol, '''\
Cell Editors are used when the
value of the cell is edited by
the user. An editor class is
wrapped around a an object
derived from wxControl and it
implements some methods required
to integrate with the grid.
''')
self.SetCellValue(16, renCol, '''\
Here are some combinations of Editors and
Renderers used together.
''')
row = 2
for label, value, renderClass, args in rendererDemoData:
renderer = apply(renderClass, args)
self.SetCellValue(row, renCol, label)
self.SetCellValue(row, renCol+1, value)
self.SetCellRenderer(row, renCol+1, renderer)
row = row + 2
row = 2
for label, value, editorClass, args in editorDemoData:
editor = apply(editorClass, args)
self.SetCellValue(row, edCol, label)
self.SetCellValue(row, edCol+1, value)
self.SetCellEditor(row, edCol+1, editor)
row = row + 2
row = 18
for label, value, renClass, edClass in comboDemoData:
self.SetCellValue(row, renCol, label)
self.SetCellValue(row, renCol+1, value)
editor = apply(edClass, ()) #args)
renderer = apply(renClass, ()) #args)
self.SetCellEditor(row, renCol+1, editor)
self.SetCellRenderer(row, renCol+1, renderer)
row = row + 2
font = self.GetFont()
font.SetWeight(wxBOLD)
attr = wxGridCellAttr()
attr.SetFont(font)
attr.SetBackgroundColour(wxLIGHT_GREY)
attr.SetReadOnly(true)
attr.SetAlignment(wxRIGHT, -1)
self.SetColAttr(renCol, attr)
self.SetColAttr(edCol, attr)
self.AutoSizeColumns(true)
self.AutoSizeRows(true)
EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick)
# I do this because I don't like the default behaviour of not starting the
# cell editor on double clicks, but only a second click.
def OnLeftDClick(self, evt):
if self.CanEnableCellControl():
self.EnableCellEditControl()
#---------------------------------------------------------------------------
class TestFrame(wxFrame):
def __init__(self, parent, log):
wxFrame.__init__(self, parent, -1, "Editors and Renderers Demo", size=(640,480))
grid = EditorsAndRenderersGrid(self, log)
#---------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = wxPySimpleApp()
frame = TestFrame(None, sys.stdout)
frame.Show(true)
app.MainLoop()
#---------------------------------------------------------------------------

View File

@@ -5,9 +5,9 @@ from wxPython.wx import *
buttonDefs = {
814 : ('GridSimple', 'Simple wxGrid, catching all events'),
815 : ('GridCustEdRend', 'wxGrid showing custom Editors and Renderers'),
816 : ('GridCustTable', 'wxGrid using a custom Table'),
817 : ('GridHugeTable', 'A wxGrid with a HUGE table (100M cells!)'),
815 : ('GridStdEdRend', 'wxGrid showing Editors and Renderers'),
818 : ('GridHugeTable', 'A wxGrid with a HUGE table (100 MILLION cells!)'),
817 : ('GridCustTable', 'wxGrid using a custom Table, with non-string data'),
}

View File

@@ -2,7 +2,7 @@
from wxPython.wx import *
import ColorPanel
import wxGrid
import GridSimple
import wxListCtrl
import wxScrolledWindow
@@ -31,7 +31,7 @@ class TestNB(wxNotebook):
win = ColorPanel.ColoredPanel(self, wxGREEN)
self.AddPage(win, "Green")
win = wxGrid.TestGrid(self, log)
win = GridSimple.SimpleGrid(self, log)
self.AddPage(win, "Grid")
win = wxListCtrl.TestListCtrlPanel(self, log)