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:
155
utils/wxPython/demo/GridCustTable.py
Normal file
155
utils/wxPython/demo/GridCustTable.py
Normal 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()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
71
utils/wxPython/demo/GridHugeTable.py
Normal file
71
utils/wxPython/demo/GridHugeTable.py
Normal 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()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
@@ -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)
|
||||
|
179
utils/wxPython/demo/GridStdEdRend.py
Normal file
179
utils/wxPython/demo/GridStdEdRend.py
Normal 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()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
@@ -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'),
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user