wxpython入门(八)列表和树形
参考书籍
http://wiki.woodpecker.org.cn/moin/WxPythonInAction
第十三章 列表控件和管理列表项
略
第十四章 网格控件
wx.grid.Grid的构造函数:
wx.grid.Grid(parent, id, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.WANTS_CHARS,
name=wxPanelNameStr)
简单示例网格,examples:
import wx
import wx.grid
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="SimpleGrid",size=(640,480))
grid = wx.grid.Grid(self)
grid.CreateGrid(50,50)
for row in range(20):
for col in range(6):
grid.SetCellValue(row,col,"cell(%d,%d)" % (row,col))
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
数据和网格分离,examples:
import wx
import wx.grid
class TestTable(wx.grid.PyGridTableBase):#定义网格表
def __init__(self):
wx.grid.PyGridTableBase.__init__(self)
self.data = { (1,1):"Here",
(2,2):"is",
(3,3):"some",
(4,4):"data",
}
self.odd=wx.grid.GridCellAttr()
self.odd.SetBackgroundColour("sky blue")
self.odd.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
self.even=wx.grid.GridCellAttr()
self.even.SetBackgroundColour("sea green")
self.even.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
# these five are the required methods
def GetNumberRows(self):
return 50
def GetNumberCols(self):
return 50
def IsEmptyCell(self, row, col):
return self.data.get((row, col)) is not None
def GetValue(self, row, col):#为网格提供数据
value = self.data.get((row, col))
if value is not None:
return value
else:
return ''
def SetValue(self, row, col, value):#给表赋值
self.data[(row,col)] = value
# the table can also provide the attribute for each cell
def GetAttr(self, row, col, kind):
attr = [self.even, self.odd][row % 2]
attr.IncRef()
return attr
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="GridTable",size=(640,480))
grid = wx.grid.Grid(self)
table = TestTable()
grid.SetTable(table, True)
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
自定义网格的标签,examples:
import wx
import wx.grid
class TestFrame(wx.Frame):
rowLabels = ["row1","row2","row3","row4","row5"]
colLabels = ["col1","col2","col3","col4","col5"]
def __init__(self):
wx.Frame.__init__(self,None,title="GridHeaders",size=(500,200))
grid = wx.grid.Grid(self)
grid.CreateGrid(5,5)
for row in range(5):
#1 start
grid.SetRowLabelValue(row, self.rowLabels[row])
grid.SetColLabelValue(row, self.colLabels[row])
#1 end
for col in range(5):
grid.SetCellValue(row,col,"(%s,%s)" % (self.rowLabels[row],self.colLabels[col]))
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
数据和grid分离的自定义标签,examples:
import wx
import wx.grid
class TestTable(wx.grid.PyGridTableBase):
def __init__(self):
wx.grid.PyGridTableBase.__init__(self)
self.rowLabels = ["row1","row2","row3","row4","row5"]
self.colLabels = ["col1","col2","col3","col4","col5"]
def GetNumberRows(self):
return 5
def GetNumberCols(self):
return 5
def IsEmptyCell(self, row, col):
return False
def GetValue(self, row, col):
return "(%s,%s)" % (self.rowLabels[row],self.colLabels[col])
def SetValue(self, row, col, value):
pass
def GetColLabelValue(self, col):#列标签
return self.colLabels[col]
def GetRowLabelValue(self, row):#行标签
return self.rowLabels[row]
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="GridTable",size=(500,200))
grid = wx.grid.Grid(self)
table = TestTable()
grid.SetTable(table, True)
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
调账单元格的大小,examples:
import wx
import wx.grid
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="GridSizes",size=(600,300))
grid = wx.grid.Grid(self)
grid.CreateGrid(5,5)
for row in range(5):
for col in range(5):
grid.SetCellValue(row,col,"(%s,%s)" % (row,col))
grid.SetCellSize(2, 2, 3, 3)#改动第2,2,让它占3行3列类似于rows,cols的作用
grid.SetColSize(0, 125)#改动第一列
grid.SetRowSize(0, 100)#改动第一行
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
改变单元格的样式和样色,examples:
import wx
import wx.grid
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="GridAttributes",size=(600,300))
grid = wx.grid.Grid(self)
grid.CreateGrid(10,6)
for row in range(10):
for col in range(6):
grid.SetCellValue(row,col,"(%s,%s)" % (row,col))
#改变cell (1,1)
grid.SetCellTextColour(1, 1, "red")
grid.SetCellFont(1,1, wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
#改变cell (2,2)
grid.SetCellBackgroundColour(2, 2, "light blue")
#定义属性
attr = wx.grid.GridCellAttr()
attr.SetTextColour("navyblue")
attr.SetBackgroundColour("pink")
attr.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
#改变cell (4,0)(5,1),row 8
grid.SetAttr(4, 0, attr)
grid.SetAttr(5, 1, attr)
grid.SetRowAttr(8, attr)
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
自定义描绘器(略)
捕获用户事件,创建自定义编辑器,examples:
import wx
import wx.grid
import string
class UpCaseCellEditor(wx.grid.PyGridCellEditor):#声明编辑器
def __init__(self):
wx.grid.PyGridCellEditor.__init__(self)
def Create(self, parent, id, evtHandler):#创建
"""
Called to create the control, which must derive from wx.Control.
*Must Override*
"""
self._tc = wx.TextCtrl(parent, id, "")
self._tc.SetInsertionPoint(0)
self.SetControl(self._tc)
if evtHandler:
self._tc.PushEventHandler(evtHandler)
self._tc.Bind(wx.EVT_CHAR, self.OnChar)
def SetSize(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._tc.SetDimensions(rect.x,rect.y,rect.width+2,rect.height+2,wx.SIZE_ALLOW_MINUS_ONE)
def BeginEdit(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._tc.SetValue(self.startValue)
self._tc.SetInsertionPointEnd()
self._tc.SetFocus()
self._tc.SetSelection(0, self._tc.GetLastPosition())
def EndEdit(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 = False
val = self._tc.GetValue()
if val != self.startValue:
changed = True
grid.GetTable().SetValue(row, col, val) # update the table
self.startValue = ''
self._tc.SetValue('')
return changed
def Reset(self):
"""
Reset the value in the control back to its starting value.
*Must Override*
"""
self._tc.SetValue(self.startValue)
self._tc.SetInsertionPointEnd()
def Clone(self):
"""
Create a new object which is the copy of this one
*Must Override*
"""
return UpCaseCellEditor()
def StartingKey(self, evt):
"""
If the editor is enabled by pressing keys on the grid, this will be
called to let the editor do something about that first key if desired.
"""
self.OnChar(evt)
if evt.GetSkipped():
self._tc.EmulateKeyPress(evt)
def OnChar(self, evt):
key = evt.GetKeyCode()
if key >= 255:
evt.Skip()
return
char = chr(key)
if char in string.letters:
char = char.upper()
self._tc.WriteText(char)#转换为大写
else:
evt.Skip()
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="Grid Editor",size=(640,480))
grid = wx.grid.Grid(self)
grid.CreateGrid(10,5)
grid.SetDefaultEditor(UpCaseCellEditor())#设置成默认编辑器
app = wx.PySimpleApp()
frame = TestFrame()
frame.Show()
app.MainLoop()
第十五章 树形控件
树形菜单
wx.TreeCtrl的构造函数:
wx.TreeControl(parent, id=-1, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS,
validator=wx.DefaultValidator, name="treeCtrl")
简单的测试示例,最先报错如下:
ImportError: No module named data
是由于没有data.py文件造成的,data.py太长,我省略了一些:
tree = [
"wx.AcceleratorTable",
"wx.BrushList",
"wx.BusyInfo",
"wx.Clipboard",
"wx.Colour",
"wx.ColourData",
"wx.ColourDatabase",
"wx.ContextHelp",
["wx.DC", [
"wx.ClientDC",
["wx.MemoryDC", [
"wx.lib.colourchooser.canvas.BitmapBuffer",
["wx.BufferedDC", [
"wx.BufferedPaintDC", ]]]],
"wx.MetaFileDC",
"wx.MirrorDC",
"wx.PaintDC",
"wx.PostScriptDC",
"wx.PrinterDC",
"wx.ScreenDC",
"wx.WindowDC",]],
"wx.DragImage"
]
树形控件示例,examples:
import wx
import data
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="SimpleTree",size=(400,500))
# Create the tree
self.tree = wx.TreeCtrl(self)
# Add a root node
root = self.tree.AddRoot("wx.Object")
# Add nodes from our data set
self.AddTreeNodes(root, data.tree)
# Bind some interesting events
self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tree)
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tree)
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)
self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivated, self.tree)
# Expand the first level
self.tree.Expand(root)
def AddTreeNodes(self, parentItem, items):
"""
Recursively traverses the data structure, adding tree nodes to
match it.
"""
for item in items:
if type(item) == str:
self.tree.AppendItem(parentItem, item)
else:
newItem = self.tree.AppendItem(parentItem, item[0])
self.AddTreeNodes(newItem, item[1])
def GetItemText(self, item):
if item:
return self.tree.GetItemText(item)
else:
return ""
def OnItemExpanded(self, evt):
print "OnItemExpanded: ", self.GetItemText(evt.GetItem())
def OnItemCollapsed(self, evt):
print "OnItemCollapsed:", self.GetItemText(evt.GetItem())
def OnSelChanged(self, evt):
print "OnSelChanged: ", self.GetItemText(evt.GetItem())
def OnActivated(self, evt):
print "OnActivated: ", self.GetItemText(evt.GetItem())
app = wx.PySimpleApp(redirect=True)
frame = TestFrame()
frame.Show()
app.MainLoop()
带图标的树形控件,examples:
import wx
import data
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="TreeWithIcons",size=(400,500))
# 创建一个图像列表
il = wx.ImageList(16,16)
# 添加图像到列表
self.fldridx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FOLDER,
wx.ART_OTHER, (16,16)))
self.fldropenidx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN,
wx.ART_OTHER, (16,16)))
self.fileidx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE,
wx.ART_OTHER, (16,16)))
# 创建树
self.tree = wx.TreeCtrl(self)
# 给树分配图像列表
self.tree.AssignImageList(il)
root = self.tree.AddRoot("wx.Object")
self.tree.SetItemImage(root, self.fldridx,wx.TreeItemIcon_Normal)
# 设置根的图像
self.tree.SetItemImage(root, self.fldropenidx,wx.TreeItemIcon_Expanded)
self.AddTreeNodes(root, data.tree)
self.tree.Expand(root)
def AddTreeNodes(self, parentItem, items):
for item in items:
if type(item) == str:
newItem = self.tree.AppendItem(parentItem, item)
self.tree.SetItemImage(newItem, self.fileidx,wx.TreeItemIcon_Normal)
# 设置数据图像
else:
newItem = self.tree.AppendItem(parentItem, item[0])
self.tree.SetItemImage(newItem, self.fldridx,wx.TreeItemIcon_Normal)
# 设置结点的图像
self.tree.SetItemImage(newItem, self.fldropenidx,wx.TreeItemIcon_Expanded)
self.AddTreeNodes(newItem, item[1])
def GetItemText(self, item):
if item:
return self.tree.GetItemText(item)
else:
return ""
app = wx.PySimpleApp(redirect=True)
frame = TestFrame()
frame.Show()
app.MainLoop()
TreeListCtrl能够显示与每行相关的数据的附加列,examples:
import wx
import wx.gizmos
import data
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title="TreeListCtrl",size=(400,500))
# Create an image list
il = wx.ImageList(16,16)
# Get some standard images from the art provider and add them
# to the image list
self.fldridx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)))
self.fldropenidx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16,16)))
self.fileidx = il.Add(
wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16,16)))
# 创建树列表控件
self.tree = wx.gizmos.TreeListCtrl(self, style =
wx.TR_DEFAULT_STYLE | wx.TR_FULL_ROW_HIGHLIGHT)
# Give it the image list
self.tree.AssignImageList(il)
#创建一些列
self.tree.AddColumn("Class Name")
self.tree.AddColumn("Description")
self.tree.SetMainColumn(0) # the one with the tree in it...
self.tree.SetColumnWidth(0, 200)
self.tree.SetColumnWidth(1, 200)
# Add a root node and assign it some images
root = self.tree.AddRoot("wx.Object")
self.tree.SetItemText(root, "A description of wx.Object", 1)#给列添加文本
self.tree.SetItemImage(root,self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(root,self.fldropenidx,wx.TreeItemIcon_Expanded)
# Add nodes from our data set
self.AddTreeNodes(root, data.tree)
# Bind some interesting events
self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tree)
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tree)
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)
self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivated, self.tree)
# Expand the first level
self.tree.Expand(root)
def AddTreeNodes(self, parentItem, items):
"""
Recursively traverses the data structure, adding tree nodes to
match it.
"""
for item in items:
if type(item) == str:
newItem = self.tree.AppendItem(parentItem, item)
self.tree.SetItemText(newItem,"A description of %s" % item,1)
#给列添加文本
self.tree.SetItemImage(newItem,self.fileidx,wx.TreeItemIcon_Normal)
else:
newItem = self.tree.AppendItem(parentItem, item[0])
self.tree.SetItemText(newItem,"A description of %s" % item[0],1)
self.tree.SetItemImage(newItem, self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(newItem, self.fldropenidx,wx.TreeItemIcon_Expanded)
self.AddTreeNodes(newItem, item[1])
def GetItemText(self, item):
if item:
return self.tree.GetItemText(item)
else:
return ""
def OnItemExpanded(self, evt):
print "OnItemExpanded: ", self.GetItemText(evt.GetItem())
def OnItemCollapsed(self, evt):
print "OnItemCollapsed:", self.GetItemText(evt.GetItem())
def OnSelChanged(self, evt):
print "OnSelChanged: ", self.GetItemText(evt.GetItem())
def OnActivated(self, evt):
print "OnActivated: ", self.GetItemText(evt.GetItem())
app = wx.PySimpleApp(redirect=True)
frame = TestFrame()
frame.Show()
app.MainLoop()